Full Code of makerdao/pymaker for AI

master 479506b356a0 cached
168 files
1.1 MB
311.5k tokens
1735 symbols
1 requests
Download .txt
Showing preview only (1,213K chars total). Download the full file or copy to clipboard to get everything.
Repository: makerdao/pymaker
Branch: master
Commit: 479506b356a0
Files: 168
Total size: 1.1 MB

Directory structure:
gitextract_8lkti2po/

├── .github/
│   └── workflows/
│       └── tests.yaml
├── .gitignore
├── .python-version
├── COPYING
├── Makefile
├── README.md
├── config/
│   ├── kovan-addresses.json
│   ├── mainnet-addresses.json
│   └── testnet-addresses.json
├── docker-compose.yml
├── docs/
│   ├── conf.py
│   └── index.rst
├── pymaker/
│   ├── __init__.py
│   ├── abi/
│   │   ├── Cat.abi
│   │   ├── Clipper.abi
│   │   ├── ClipperCallee.abi
│   │   ├── DSAuth.abi
│   │   ├── DSChief.abi
│   │   ├── DSEthToken.abi
│   │   ├── DSGuard.abi
│   │   ├── DSPause.abi
│   │   ├── DSProxy.abi
│   │   ├── DSProxyCache.abi
│   │   ├── DSProxyFactory.abi
│   │   ├── DSRoles.abi
│   │   ├── DSToken.abi
│   │   ├── DSValue.abi
│   │   ├── DSVault.abi
│   │   ├── DaiJoin.abi
│   │   ├── Dog.abi
│   │   ├── DsrManager.abi
│   │   ├── DssCdpManager.abi
│   │   ├── DssProxyActionsDsr.abi
│   │   ├── ERC20Token.abi
│   │   ├── ESM.abi
│   │   ├── End.abi
│   │   ├── EtherDelta.abi
│   │   ├── EtherToken.abi
│   │   ├── Exchange.abi
│   │   ├── ExchangeV2-ERC20Proxy.abi
│   │   ├── ExchangeV2.abi
│   │   ├── Flapper.abi
│   │   ├── Flipper.abi
│   │   ├── Flopper.abi
│   │   ├── GemJoin.abi
│   │   ├── GemJoin5.abi
│   │   ├── Jug.abi
│   │   ├── MakerOtcSupportMethods.abi
│   │   ├── MatchingMarket.abi
│   │   ├── OSM.abi
│   │   ├── Pit.abi
│   │   ├── Pot.abi
│   │   ├── ProxyRegistry.abi
│   │   ├── SaiTap.abi
│   │   ├── SaiTop.abi
│   │   ├── SaiTub.abi
│   │   ├── SaiVox.abi
│   │   ├── SimpleMarket.abi
│   │   ├── Spotter.abi
│   │   ├── TokenFaucet.abi
│   │   ├── TokenTransferProxy.abi
│   │   ├── TxManager.abi
│   │   ├── Vat.abi
│   │   ├── Vow.abi
│   │   ├── ZRXToken.abi
│   │   └── diff-abi.sh
│   ├── approval.py
│   ├── auctions.py
│   ├── auth.py
│   ├── cdpmanager.py
│   ├── collateral.py
│   ├── deployment.py
│   ├── dsr.py
│   ├── dsrmanager.py
│   ├── dss.py
│   ├── etherdelta.py
│   ├── feed.py
│   ├── gas.py
│   ├── governance.py
│   ├── ilk.py
│   ├── join.py
│   ├── keys.py
│   ├── lifecycle.py
│   ├── logging.py
│   ├── model.py
│   ├── numeric.py
│   ├── oasis.py
│   ├── oracles.py
│   ├── proxy.py
│   ├── reloadable_config.py
│   ├── sai.py
│   ├── shutdown.py
│   ├── sign.py
│   ├── tightly_packed.py
│   ├── token.py
│   ├── transactional.py
│   ├── util.py
│   ├── vault.py
│   ├── zrx.py
│   └── zrxv2.py
├── requirements-dev.txt
├── requirements.txt
├── setup.py
├── test-dss.sh
├── test.sh
├── tests/
│   ├── __init__.py
│   ├── abi/
│   │   ├── DaiMock.abi
│   │   ├── DaiMock.sol
│   │   ├── GemMock.abi
│   │   ├── GemMock.sol
│   │   ├── OasisMockPriceOracle.abi
│   │   └── OasisMockPriceOracle.sol
│   ├── accounts/
│   │   ├── 0_0x9596c16d7bf9323265c2f2e22f43e6c80eb3d943.json
│   │   ├── 1_0xe415482ca06eeb684ad3f758c2129fca4b1eb1f4.json
│   │   ├── 2_0x270b0e8d873e858abd698a000b0da0b94e21d84c.json
│   │   ├── 3_0x812e87be5d4198fca55cb52fa60cb46620617474.json
│   │   ├── 4_0x13314e21cd6d343ceb857073f3f6d9368919d1ef.json
│   │   ├── 5_0x176087fea5c41fc370fabbd850521bc4451690ca.json
│   │   └── pass
│   ├── config/
│   │   ├── keys/
│   │   │   └── UnlimitedChain/
│   │   │       ├── key.json
│   │   │       ├── key1.json
│   │   │       ├── key2.json
│   │   │       ├── key3.json
│   │   │       └── key4.json
│   │   └── parity-dev-constantinopole.json
│   ├── conftest.py
│   ├── dss_token.py
│   ├── helpers.py
│   ├── manual_test_async_tx.py
│   ├── manual_test_cdpmanager.py
│   ├── manual_test_dsr.py
│   ├── manual_test_goerli.py
│   ├── manual_test_mcd.py
│   ├── manual_test_node.py
│   ├── manual_test_tx_recovery.py
│   ├── manual_test_zrxv2.py
│   ├── test_approval.py
│   ├── test_auctions.py
│   ├── test_auth.py
│   ├── test_cdpmanager.py
│   ├── test_dsrmanager.py
│   ├── test_dss.py
│   ├── test_etherdelta.py
│   ├── test_feed.py
│   ├── test_gas.py
│   ├── test_general.py
│   ├── test_general2.py
│   ├── test_governance.py
│   ├── test_keys.py
│   ├── test_lifecycle.py
│   ├── test_model.py
│   ├── test_numeric.py
│   ├── test_oasis.py
│   ├── test_proxy.py
│   ├── test_reloadable_config.py
│   ├── test_sai.py
│   ├── test_savings.py
│   ├── test_shutdown.py
│   ├── test_sign.py
│   ├── test_token.py
│   ├── test_transactional.py
│   ├── test_util.py
│   ├── test_vault.py
│   ├── test_zrx.py
│   └── test_zrxv2.py
└── utils/
    └── etherdelta-client/
        ├── .gitignore
        ├── main.js
        └── package.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/tests.yaml
================================================
on:
  # Trigger the workflow on push or pull request,
  # but only for the main branch
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:

      - name: Checkout repository and submodules
        uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: setup python
        uses: actions/setup-python@v4
        with:
          python-version: '3.8'

      - name: install python packages
        run: |
          python -m pip install --upgrade pip
          pip install virtualenv --upgrade
          pip install -r requirements.txt
          pip install -r requirements-dev.txt
      - name: execute tests
        run: ./test.sh


================================================
FILE: .gitignore
================================================
.idea
*.iml

__pycache__
.cache
.coverage
.pytest_cache

.DS_Store

logs/*.json.log
tests/config/keys/UnlimitedChain/address_book.json

docs/_doc
_virtualenv


================================================
FILE: .python-version
================================================
3.6.6


================================================
FILE: COPYING
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 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.

    <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 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 <http://www.gnu.org/licenses/>.

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
<http://www.gnu.org/licenses/>.


================================================
FILE: Makefile
================================================
help:           ## Show this help.
	@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'

doc-clean:      ## Clean the documentation output directory
	cd docs; rm -rf _doc

doc-build: doc-clean        ## Build the documentation
	cd docs; sphinx-build . _doc

doc-open: doc-build         ## Open the documentation
	cd docs; open _doc/index.html

doc-deploy: doc-build       ## Deploy the documentation at http://maker-keeper-docs.surge.sh
	cd docs; surge --project _doc --domain maker-keeper-docs.surge.sh


================================================
FILE: README.md
================================================
# pymaker

Python API for Maker contracts.

![Build Status](https://github.com/makerdao/pymaker/actions/workflows/.github/workflows/tests.yaml/badge.svg?branch=master)

<https://chat.makerdao.com/channel/keeper>

## Introduction

The _DAI Stablecoin System_ incentivizes external agents, called _keepers_,
to automate certain operations around the Ethereum blockchain. In order to ease their
development, an API around most of the Maker contracts has been created. It can be used
not only by keepers, but may also be found useful by authors of some other, unrelated
utilities aiming to interact with these contracts.

Based on this API, a set of reference Maker keepers is being developed. They all used to reside
in this repository, but now each of them has an individual one: 
[bite-keeper](https://github.com/makerdao/bite-keeper) (SCD only),
[arbitrage-keeper](https://github.com/makerdao/arbitrage-keeper),
[auction-keeper](https://github.com/makerdao/auction-keeper) (MCD only),
[cdp-keeper](https://github.com/makerdao/cdp-keeper) (SCD only),
[market-maker-keeper](https://github.com/makerdao/market-maker-keeper).

You only need to install this project directly if you want to build your own keepers,
or if you want to play with this API library itself. If you just want to install
one of reference keepers, go to one of the repositories linked above and start from there.
Each of these keepers references some version of `pymaker` via a Git submodule.

## Installation

This project uses *Python 3.6.6*.

In order to clone the project and install required third-party packages please execute:
```
git clone https://github.com/makerdao/pymaker.git
cd pymaker
pip3 install -r requirements.txt
```

### Known Ubuntu issues

In order for the `secp256k` Python dependency to compile properly, following packages will need to be installed:
```
sudo apt-get install build-essential automake libtool pkg-config libffi-dev python-dev python-pip libsecp256k1-dev
```

(for Ubuntu 18.04 Server)

### Known macOS issues

In order for the Python requirements to install correctly on _macOS_, please install
`openssl`, `libtool`, `pkg-config` and `automake` using [Homebrew](https://brew.sh/):
```
brew install openssl libtool pkg-config automake
```

and set the `LDFLAGS` environment variable before you run `pip3 install -r requirements.txt`:
```
export LDFLAGS="-L$(brew --prefix openssl)/lib" CFLAGS="-I$(brew --prefix openssl)/include" 
```

### Known node issues
 * `pymaker` has been tested against **Parity/OpenEthereum** and **Geth**.  It has not been tested against **Hyperledger Besu**.
 * Many Ethereum node providers do not support the full [JSON-RPC API](https://eth.wiki/json-rpc/API#json-rpc-methods). 
As such, certain JSON-RPC calls in `__init__.py` may not function properly.  
 * Some node providers only support certain calls using websocket endpoints.  Unfortunately, Web3.py's 
 `WebsocketProvider` [does not support](https://github.com/ethereum/web3.py/issues/1413) multiple threads awaiting a 
 response from the websocket, breaking some core `pymaker` functionality in `Lifecycle` and `Transact` classes.
 * When using an **Infura** node to pull event logs, ensure your requests are batched into a small enough chunks such 
 that no more than 10,000 results will be returned for each request.
 * Asynchronous submission of simultaneous transactions often doesn't work on third-party node providers because RPC 
 calls to `parity_nextNonce` and `getTransactionCount` are inappropriately proxied, cached, or just plain not 
 supported.  To remedy this, a serial-incrementing nonce is used for these providers' URLs.  The downside to a serial-
 incrementing nonce is that transactions submitted for the same account from another wallet or keeper will bring the 
 next nonce out-of-alignment, causing transaction failures or unexpected replacements.  To work around this, stop the 
 application, wait for pending transactions for the account to be mined, and then restart the application.  
 * Recovery of pending transactions does not work on certain third-party node providers.


## Available APIs

The current version provides APIs around:
* `ERC20Token`,
* `Tub`, `Tap`,`Top` and `Vox` (<https://github.com/makerdao/sai>),
* `Vat`, `Cat`, `Vow`, `Jug`, `Flipper`, `Flapper`, `Flopper` (<https://github.com/makerdao/dss>)
* `SimpleMarket`, `ExpiringMarket` and `MatchingMarket` (<https://github.com/makerdao/maker-otc>),
* `TxManager` (<https://github.com/makerdao/tx-manager>),
* `DSGuard` (<https://github.com/dapphub/ds-guard>),
* `DSToken` (<https://github.com/dapphub/ds-token>),
* `DSEthToken` (<https://github.com/dapphub/ds-eth-token>),
* `DSValue` (<https://github.com/dapphub/ds-value>),
* `DSVault` (<https://github.com/dapphub/ds-vault>),
* `EtherDelta` (<https://github.com/etherdelta/etherdelta.github.io>),
* `0x v1` (<https://etherscan.io/address/0x12459c951127e0c374ff9105dda097662a027093#code>, <https://github.com/0xProject/standard-relayer-api>),
* `0x v2`.

APIs around the following functionality have not been implemented:
* Governance (`DSAuth`, `DSGuard`, `DSSpell`, `Mom`)

Contributions from the community are appreciated.

## Code samples

Below you can find some code snippets demonstrating how the API can be used both for developing
your own keepers and for creating some other utilities interacting with the _DAI Stablecoin_
ecosystem contracts.

### Token transfer

This snippet demonstrates how to transfer some SAI from our default address. The SAI token address
is discovered by querying the `Tub`, so all we need as a `Tub` address:

```python
from web3 import HTTPProvider, Web3

from pymaker import Address
from pymaker.token import ERC20Token
from pymaker.numeric import Wad
from pymaker.sai import Tub


web3 = Web3(HTTPProvider(endpoint_uri="http://localhost:8545"))

tub = Tub(web3=web3, address=Address('0xb7ae5ccabd002b5eebafe6a8fad5499394f67980'))
sai = ERC20Token(web3=web3, address=tub.sai())

sai.transfer(address=Address('0x0000000000111111111100000000001111111111'),
             value=Wad.from_number(10)).transact()
``` 

### Updating a DSValue

This snippet demonstrates how to update a `DSValue` with the ETH/USD rate pulled from _CryptoCompare_: 

```python
import json
import urllib.request

from web3 import HTTPProvider, Web3

from pymaker import Address
from pymaker.feed import DSValue
from pymaker.numeric import Wad


def cryptocompare_rate() -> Wad:
    with urllib.request.urlopen("https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD") as url:
        data = json.loads(url.read().decode())
        return Wad.from_number(data['USD'])


web3 = Web3(HTTPProvider(endpoint_uri="http://localhost:8545"))

dsvalue = DSValue(web3=web3, address=Address('0x038b3d8288df582d57db9be2106a27be796b0daf'))
dsvalue.poke_with_int(cryptocompare_rate().value).transact()
```

### SAI introspection

This snippet demonstrates how to fetch data from `Tub` and `Tap` contracts:

```python
from web3 import HTTPProvider, Web3

from pymaker import Address
from pymaker.token import ERC20Token
from pymaker.numeric import Ray
from pymaker.sai import Tub, Tap


web3 = Web3(HTTPProvider(endpoint_uri="http://localhost:8545"))

tub = Tub(web3=web3, address=Address('0x448a5065aebb8e423f0896e6c5d525c040f59af3'))
tap = Tap(web3=web3, address=Address('0xbda109309f9fafa6dd6a9cb9f1df4085b27ee8ef'))
sai = ERC20Token(web3=web3, address=tub.sai())
skr = ERC20Token(web3=web3, address=tub.skr())
gem = ERC20Token(web3=web3, address=tub.gem())

print(f"")
print(f"Token summary")
print(f"-------------")
print(f"SAI total supply       : {sai.total_supply()} SAI")
print(f"SKR total supply       : {skr.total_supply()} SKR")
print(f"GEM total supply       : {gem.total_supply()} GEM")
print(f"")
print(f"Collateral summary")
print(f"------------------")
print(f"GEM collateral         : {tub.pie()} GEM")
print(f"SKR collateral         : {tub.air()} SKR")
print(f"SKR pending liquidation: {tap.fog()} SKR")
print(f"")
print(f"Debt summary")
print(f"------------")
print(f"Debt ceiling           : {tub.cap()} SAI")
print(f"Good debt              : {tub.din()} SAI")
print(f"Bad debt               : {tap.woe()} SAI")
print(f"Surplus                : {tap.joy()} SAI")
print(f"")
print(f"Feed summary")
print(f"------------")
print(f"REF per GEM feed       : {tub.pip()}")
print(f"REF per SKR price      : {tub.tag()}")
print(f"GEM per SKR price      : {tub.per()}")
print(f"")
print(f"Tub parameters")
print(f"--------------")
print(f"Liquidation ratio      : {tub.mat()*100} %")
print(f"Liquidation penalty    : {tub.axe()*100 - Ray.from_number(100)} %")
print(f"Stability fee          : {tub.tax()} %")
print(f"")
print(f"All cups")
print(f"--------")
for cup_id in range(1, tub.cupi()+1):
    cup = tub.cups(cup_id)
    print(f"Cup #{cup_id}, lad={cup.lad}, ink={cup.ink} SKR, tab={tub.tab(cup_id)} SAI, safe={tub.safe(cup_id)}")
```

### Multi-collateral Dai

This snippet demonstrates how to create a CDP and draw Dai.

```python
import sys
from web3 import Web3, HTTPProvider

from pymaker import Address
from pymaker.deployment import DssDeployment
from pymaker.keys import register_keys
from pymaker.numeric import Wad


web3 = Web3(HTTPProvider(endpoint_uri="https://localhost:8545",
                         request_kwargs={"timeout": 10}))
web3.eth.defaultAccount = sys.argv[1]   # ex: 0x0000000000000000000000000000000aBcdef123
register_keys(web3, [sys.argv[2]])      # ex: key_file=~keys/default-account.json,pass_file=~keys/default-account.pass

mcd = DssDeployment.from_json(web3=web3, conf=open("tests/config/kovan-addresses.json", "r").read())
our_address = Address(web3.eth.defaultAccount)


# Choose the desired collateral; in this case we'll wrap some Eth
collateral = mcd.collaterals['ETH-A']
ilk = collateral.ilk
collateral.gem.deposit(Wad.from_number(3)).transact()

# Add collateral and allocate the desired amount of Dai
collateral.approve(our_address)
collateral.adapter.join(our_address, Wad.from_number(3)).transact()
mcd.vat.frob(ilk, our_address, dink=Wad.from_number(3), dart=Wad.from_number(153)).transact()
print(f"CDP Dai balance before withdrawal: {mcd.vat.dai(our_address)}")

# Mint and withdraw our Dai
mcd.approve_dai(our_address)
mcd.dai_adapter.exit(our_address, Wad.from_number(153)).transact()
print(f"CDP Dai balance after withdrawal:  {mcd.vat.dai(our_address)}")

# Repay (and burn) our Dai
assert mcd.dai_adapter.join(our_address, Wad.from_number(153)).transact()
print(f"CDP Dai balance after repayment:   {mcd.vat.dai(our_address)}")

# Withdraw our collateral
mcd.vat.frob(ilk, our_address, dink=Wad(0), dart=Wad.from_number(-153)).transact()
mcd.vat.frob(ilk, our_address, dink=Wad.from_number(-3), dart=Wad(0)).transact()
collateral.adapter.exit(our_address, Wad.from_number(3)).transact()
print(f"CDP Dai balance w/o collateral:    {mcd.vat.dai(our_address)}")
```

### Asynchronous invocation of Ethereum transactions

This snippet demonstrates how multiple token transfers can be executed asynchronously:

```python
from web3 import HTTPProvider
from web3 import Web3

from pymaker import Address, synchronize
from pymaker.numeric import Wad
from pymaker.sai import Tub
from pymaker.token import ERC20Token


web3 = Web3(HTTPProvider(endpoint_uri="http://localhost:8545"))

tub = Tub(web3=web3, address=Address('0x448a5065aebb8e423f0896e6c5d525c040f59af3'))
sai = ERC20Token(web3=web3, address=tub.sai())
skr = ERC20Token(web3=web3, address=tub.skr())

synchronize([sai.transfer(Address('0x0101010101020202020203030303030404040404'), Wad.from_number(1.5)).transact_async(),
             skr.transfer(Address('0x0303030303040404040405050505050606060606'), Wad.from_number(2.5)).transact_async()])
```

### Multiple invocations in one Ethereum transaction

This snippet demonstrates how multiple token transfers can be executed in one Ethereum transaction.
A `TxManager` instance has to be deployed and owned by the caller.

```python
from web3 import HTTPProvider
from web3 import Web3

from pymaker import Address
from pymaker.approval import directly
from pymaker.numeric import Wad
from pymaker.sai import Tub
from pymaker.token import ERC20Token
from pymaker.transactional import TxManager


web3 = Web3(HTTPProvider(endpoint_uri="http://localhost:8545"))

tub = Tub(web3=web3, address=Address('0x448a5065aebb8e423f0896e6c5d525c040f59af3'))
sai = ERC20Token(web3=web3, address=tub.sai())
skr = ERC20Token(web3=web3, address=tub.skr())

tx = TxManager(web3=web3, address=Address('0x57bFE16ae8fcDbD46eDa9786B2eC1067cd7A8f48'))
tx.approve([sai, skr], directly())

tx.execute([sai.address, skr.address],
           [sai.transfer(Address('0x0101010101020202020203030303030404040404'), Wad.from_number(1.5)).invocation(),
            skr.transfer(Address('0x0303030303040404040405050505050606060606'), Wad.from_number(2.5)).invocation()]).transact()
```

### Ad-hoc increasing of gas price for asynchronous transactions

```python
import asyncio
from random import randint

from web3 import Web3, HTTPProvider

from pymaker import Address
from pymaker.gas import FixedGasPrice
from pymaker.oasis import SimpleMarket


web3 = Web3(HTTPProvider(endpoint_uri=f"http://localhost:8545"))
otc = SimpleMarket(web3=web3, address=Address('0x375d52588c3f39ee7710290237a95C691d8432E7'))


async def bump_with_increasing_gas_price(order_id):
    gas_price = FixedGasPrice(gas_price=1000000000)
    task = asyncio.ensure_future(otc.bump(order_id).transact_async(gas_price=gas_price))

    while not task.done():
        await asyncio.sleep(1)
        gas_price.update_gas_price(gas_price.gas_price + randint(0, gas_price.gas_price))

    return task.result()


bump_task = asyncio.ensure_future(bump_with_increasing_gas_price(otc.get_orders()[-1].order_id))
event_loop = asyncio.get_event_loop()
bump_result = event_loop.run_until_complete(bump_task)

print(bump_result)
print(bump_result.transaction_hash)
```

## Testing

Prerequisites:
* [docker and docker-compose](https://www.docker.com/get-started) - for containerized deployments of Ganache and Parity
* [seth](https://dapp.tools/seth/) - to enable the token faucet

This project uses [pytest](https://docs.pytest.org/en/latest/) for unit testing.  Testing of Multi-collateral Dai is 
performed on a Dockerized local testchain included in `tests\config`.

In order to be able to run tests, please install development dependencies first by executing:
```
pip3 install -r requirements-dev.txt
```

You can then run all tests with:
```
./test.sh
```

By default, `pymaker` will not send a transaction to the chain if gas estimation fails, because this means the 
transaction would revert.  For testing purposes, it is sometimes useful to send bad transactions to the chain.  To 
accomplish this, set class variable `gas_estimate_for_bad_txs` in your application.  For example:
```
from pymaker import Transact
Transact.gas_estimate_for_bad_txs = 200000
```

## License

See [COPYING](https://github.com/makerdao/pymaker/blob/master/COPYING) file.


================================================
FILE: config/kovan-addresses.json
================================================
{
  "CHANGELOG": "0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F",
  "MULTICALL": "0xC6D81A2e375Eee15a20E6464b51c5FC6Bb949fdA",
  "FAUCET": "0x57aAeAE905376a4B1899bA81364b4cE2519CBfB3",
  "MCD_DEPLOY": "0x13141b8a5E4A82Ebc6b636849dd6A515185d6236",
  "FLIP_FAB": "0x7c890e1e492FDDA9096353D155eE1B26C1656a62",
  "CLIP_FAB": "0x54659eebDFB1Dd0b53ed2252ed344a8dCbCC96CD",
  "CALC_FAB": "0xA81598667AC561986b70ae11bBE2dd5348ed4327",
  "LERP_FAB": "0xa6766Ed3574bAFc6114618E74035C7bb5e9a6aa9",
  "MCD_GOV": "0xAaF64BFCC32d0F15873a02163e7E500671a4ffcD",
  "GOV_GUARD": "0xE50303C6B67a2d869684EFb09a62F6aaDD06387B",
  "MCD_ADM": "0x27E0c9567729Ea6e3241DE74B3dE499b7ddd3fe6",
  "VOTE_PROXY_FACTORY": "0x1400798AA746457E467A1eb9b3F3f72C25314429",
  "MCD_VAT": "0xbA987bDB501d131f766fEe8180Da5d81b34b69d9",
  "MCD_JUG": "0xcbB7718c9F39d05aEEDE1c472ca8Bf804b2f1EaD",
  "MCD_CAT": "0xdDb5F7A3A5558b9a6a1f3382BD75E2268d1c6958",
  "MCD_DOG": "0x121D0953683F74e9a338D40d9b4659C0EBb539a0",
  "MCD_VOW": "0x0F4Cbe6CBA918b7488C26E29d9ECd7368F38EA3b",
  "MCD_JOIN_DAI": "0x5AA71a3ae1C0bd6ac27A1f28e1415fFFB6F15B8c",
  "MCD_FLAP": "0xc6d3C83A080e2Ef16E4d7d4450A869d0891024F5",
  "MCD_FLOP": "0x52482a3100F79FC568eb2f38C4a45ba457FBf5fA",
  "MCD_PAUSE": "0x8754E6ecb4fe68DaA5132c2886aB39297a5c7189",
  "MCD_PAUSE_PROXY": "0x0e4725db88Bb038bBa4C4723e91Ba183BE11eDf3",
  "MCD_GOV_ACTIONS": "0x0Ca17E81073669741714354f16D800af64e95C75",
  "MCD_DAI": "0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa",
  "MCD_SPOT": "0x3a042de6413eDB15F2784f2f97cC68C7E9750b2D",
  "MCD_POT": "0xEA190DBDC7adF265260ec4dA6e9675Fd4f5A78bb",
  "MCD_END": "0x3d9603037FF096af03B83725dFdB1CDA9EA02CE4",
  "MCD_ESM": "0xD5D728446275B0A12E4a4038527974b92353B4a9",
  "PROXY_ACTIONS": "0xd1D24637b9109B7f61459176EdcfF9Be56283a7B",
  "PROXY_ACTIONS_END": "0x7c3f28f174F2b0539C202a5307Ff48efa61De982",
  "PROXY_ACTIONS_DSR": "0xc5CC1Dfb64A62B9C7Bb6Cbf53C2A579E2856bf92",
  "CDP_MANAGER": "0x1476483dD8C35F25e568113C5f70249D3976ba21",
  "DSR_MANAGER": "0x7f5d60432DE4840a3E7AE7218f7D6b7A2412683a",
  "GET_CDPS": "0x592301a23d37c591C5856f28726AF820AF8e7014",
  "ILK_REGISTRY": "0xc3F42deABc0C506e8Ae9356F2d4fc1505196DCDB",
  "OSM_MOM": "0x5dA9D1C3d4f1197E5c52Ff963916Fe84D2F5d8f3",
  "FLIPPER_MOM": "0x50dC6120c67E456AdA2059cfADFF0601499cf681",
  "CLIPPER_MOM": "0x96E9a19Be6EA91d1C0908e5E207f944dc2E7B878",
  "MCD_IAM_AUTO_LINE": "0xe7D7d61c0ed9306B6c93E7C65F6C9DDF38b9320b",
  "PROXY_FACTORY": "0xe11E3b391F7E8bC47247866aF32AF67Dd58Dc800",
  "PROXY_REGISTRY": "0x64A436ae831C1672AE81F674CAb8B6775df3475C",
  "ETH": "0xd0A1E359811322d97991E03f863a0C30C2cF029C",
  "PIP_ETH": "0x75dD74e8afE8110C8320eD397CcCff3B8134d981",
  "MCD_JOIN_ETH_A": "0x775787933e92b709f2a3C70aa87999696e74A9F8",
  "MCD_CLIP_ETH_A": "0x7dD1Fb6b9aFdBA9F28DB89c81723b8c6B27A2Fbe",
  "MCD_CLIP_CALC_ETH_A": "0x46bE29C1993d64f0C93e81D69FfAFDF4881806f2",
  "MCD_JOIN_ETH_B": "0xd19A770F00F89e6Dd1F12E6D6E6839b95C084D85",
  "MCD_CLIP_ETH_B": "0x004676c737FC75A2799dFe745d23F5597620Ad43",
  "MCD_CLIP_CALC_ETH_B": "0x4672215ADF0556Af60261e97E221c875ce9F0863",
  "MCD_JOIN_ETH_C": "0xD166b57355BaCE25e5dEa5995009E68584f60767",
  "MCD_CLIP_ETH_C": "0x86D5eA244cf6c79227CA73004C963b72431f23ac",
  "MCD_CLIP_CALC_ETH_C": "0xa8AfB2680cced6de0E1dfe5C35F0FEdFB8E95720",
  "BAT": "0x9f8cFB61D3B2aF62864408DD703F9C3BEB55dff7",
  "PIP_BAT": "0x5C40C9Eb35c76069fA4C3A00EA59fAc6fFA9c113",
  "MCD_JOIN_BAT_A": "0x2a4C485B1B8dFb46acCfbeCaF75b6188A59dBd0a",
  "MCD_CLIP_BAT_A": "0x332B44A24e2CF8A258E8A1932b13296b9316a74c",
  "MCD_CLIP_CALC_BAT_A": "0x4AB9058A9cAB0B18B4b40621Fa44B2131836Ad32",
  "USDC": "0xBD84be3C303f6821ab297b840a99Bd0d4c4da6b5",
  "PIP_USDC": "0x4c51c2584309b7BF328F89609FDd03B3b95fC677",
  "MCD_JOIN_USDC_A": "0x4c514656E7dB7B859E994322D2b511d99105C1Eb",
  "MCD_CLIP_USDC_A": "0x09D45087c035DbcD8d6fB5e9d4c5341b9101E626",
  "MCD_CLIP_CALC_USDC_A": "0xF8D26c26Ac481794E4Aebf4F35B10d8E9748086a",
  "MCD_JOIN_USDC_B": "0xaca10483e7248453BB6C5afc3e403e8b7EeDF314",
  "MCD_CLIP_USDC_B": "0xedFc36f75faafa80e39cd4623def15da6CF2B5C0",
  "MCD_CLIP_CALC_USDC_B": "0x275076c9c101AF880BD944991258d564FA31D61B",
  "WBTC": "0x7419f744bBF35956020C1687fF68911cD777f865",
  "PIP_WBTC": "0x2f38a1bD385A9B395D01f2Cbf767b4527663edDB",
  "MCD_JOIN_WBTC_A": "0xB879c7d51439F8e7AC6b2f82583746A0d336e63F",
  "MCD_CLIP_WBTC_A": "0x5518C2f409Bed4bD5FF3542d9D5002251EEDA892",
  "MCD_CLIP_CALC_WBTC_A": "0x2c39F8C9aE16B84076D7fEA15CE5855925a09DA6",
  "TUSD": "0xD6CE59F06Ff2070Dd5DcAd0866A7D8cd9270041a",
  "PIP_TUSD": "0xE4bAECdba7A8Ff791E14c6BF7e8089Dfdf75C7E7",
  "MCD_JOIN_TUSD_A": "0xe53f6755A031708c87d80f5B1B43c43892551c17",
  "MCD_CLIP_TUSD_A": "0x9D547d599489B3950485cBa119FC37Bba9c15c13",
  "MCD_CLIP_CALC_TUSD_A": "0x4AE93701287b8C86f17E5a0Cb4D0732b5ae6EFBD",
  "ZRX": "0xC2C08A566aD44129E69f8FC98684EAA28B01a6e7",
  "PIP_ZRX": "0x218037a42947E634191A231fcBAEAE8b16a39b3f",
  "MCD_JOIN_ZRX_A": "0x85D38fF6a6FCf98bD034FB5F9D72cF15e38543f2",
  "MCD_CLIP_ZRX_A": "0x9072C477FEb67eEFd8865737206e87570444885E",
  "MCD_CLIP_CALC_ZRX_A": "0xCd8Aa54176A333C3B668f65Ff8F11ee909f9A698",
  "KNC": "0x9800a0a3c7e9682e1AEb7CAA3200854eFD4E9327",
  "PIP_KNC": "0x10799280EF9d7e2d037614F5165eFF2cB8522651",
  "MCD_JOIN_KNC_A": "0xE42427325A0e4c8e194692FfbcACD92C2C381598",
  "MCD_CLIP_KNC_A": "0x09EA13E49885C29dD270B5c3F557D71A30479333",
  "MCD_CLIP_CALC_KNC_A": "0x8D11DC42F5Cc6fE19FeE799e3e24b506cEadAB4b",
  "MANA": "0x221F4D62636b7B51b99e36444ea47Dc7831c2B2f",
  "PIP_MANA": "0xE97D2b077Fe19c80929718d377981d9F754BF36e",
  "MCD_JOIN_MANA_A": "0xdC9Fe394B27525e0D9C827EE356303b49F607aaF",
  "MCD_CLIP_MANA_A": "0xFd79e5881CC59F4637ddb3799D302BF089dEE832",
  "MCD_CLIP_CALC_MANA_A": "0x14cd62bB700d3cDe2bC45Db2875b58200DDD2503",
  "USDT": "0x9245BD36FA20fcD292F4765c4b5dF83Dc3fD5e86",
  "PIP_USDT": "0x3588A7973D41AaeA7B203549553C991C4311951e",
  "MCD_JOIN_USDT_A": "0x9B011a74a690dFd9a1e4996168d3EcBDE73c2226",
  "MCD_CLIP_USDT_A": "0xBDd2d10dAF8D86dA1f02bB7c7C7841bC9A4F62D4",
  "MCD_CLIP_CALC_USDT_A": "0xa3a5163Fa4d46D799fE4B036349f0289D69A4445",
  "PAXUSD": "0xa6383AF46c36219a472b9549d70E4768dfA8894c",
  "PIP_PAXUSD": "0xD01fefed46eb21cd057bAa14Ff466842C31a0Cd9",
  "MCD_JOIN_PAXUSD_A": "0x3d6a14C9542B429a4e3d255F6687754d4898D897",
  "MCD_CLIP_PAXUSD_A": "0x3939B686a0A7265512D38Ea3fe700812A703BF31",
  "MCD_CLIP_CALC_PAXUSD_A": "0x784863edC4C28D73192bf56944D8803c0b5E0CbF",
  "COMP": "0x1dDe24ACE93F9F638Bfd6fCE1B38b842703Ea1Aa",
  "PIP_COMP": "0xcc10b1C53f4BFFEE19d0Ad00C40D7E36a454D5c4",
  "MCD_JOIN_COMP_A": "0x16D567c1F6824ffFC460A11d48F61E010ae43766",
  "MCD_CLIP_COMP_A": "0xCDe79465D0B98775c1831957b88BFa12b8A3f020",
  "MCD_CLIP_CALC_COMP_A": "0x3e41fCB2DC5370F8612884CB2928E74FED77Cb4B",
  "LRC": "0xF070662e48843934b5415f150a18C250d4D7B8aB",
  "PIP_LRC": "0xcEE47Bb8989f625b5005bC8b9f9A0B0892339721",
  "MCD_JOIN_LRC_A": "0x436286788C5dB198d632F14A20890b0C4D236800",
  "MCD_CLIP_LRC_A": "0xaF94A206A3f3948c0BDB6a195a119862F26F5e92",
  "MCD_CLIP_CALC_LRC_A": "0xD47DF2Cae1a86fC22e8A8b9B06b22f27860Cb333",
  "LINK": "0xa36085F69e2889c224210F603D836748e7dC0088",
  "PIP_LINK": "0x20D5A457e49D05fac9729983d9701E0C3079Efac",
  "MCD_JOIN_LINK_A": "0xF4Df626aE4fb446e2Dcce461338dEA54d2b9e09b",
  "MCD_CLIP_LINK_A": "0x1eB71cC879960606F8ab0E02b3668EEf92CE6D98",
  "MCD_CLIP_CALC_LINK_A": "0xbd586d6352Fcf0C45f77FC9348F4Ee7539F6e2bD",
  "BAL": "0x630D82Cbf82089B09F71f8d3aAaff2EBA6f47B15",
  "PIP_BAL": "0x4fd34872F3AbC07ea6C45c7907f87041C0801DdE",
  "MCD_JOIN_BAL_A": "0x8De5EA9251E0576e3726c8766C56E27fAb2B6597",
  "MCD_CLIP_BAL_A": "0x8F6C48A26ebf4006Ab542d030D4090DfeC39652E",
  "MCD_CLIP_CALC_BAL_A": "0xd041ED45EC5e4539BbbCd91B97D36C76F9d678C9",
  "YFI": "0x251F1c3077FEd1770cB248fB897100aaE1269FFC",
  "PIP_YFI": "0x9D8255dc4e25bB85e49c65B21D8e749F2293862a",
  "MCD_JOIN_YFI_A": "0x5b683137481F2FE683E2f2385792B1DeB018050F",
  "MCD_CLIP_YFI_A": "0x9020C96B06d2ac59e98A0F35f131D491EEcAa2C2",
  "MCD_CLIP_CALC_YFI_A": "0x54A18C6ceEBDf42D8532EBf5e0a67C430a51b2f6",
  "GUSD": "0x31D8EdbF6F33ef858c80d68D06Ec83f33c2aA150",
  "PIP_GUSD": "0xb6630DE6Eda0f3f3d96Db4639914565d6b82CfEF",
  "MCD_JOIN_GUSD_A": "0x0c6B26e6AB583D2e4528034037F74842ea988909",
  "MCD_CLIP_GUSD_A": "0x448eD0ff4e154C1cBefE2c8057906Dd3dA194dA5",
  "MCD_CLIP_CALC_GUSD_A": "0x4DD8AaB74a710E7a95937ef1b2618ee76F829Ba6",
  "UNI": "0x0C527850e5D6B2B406F1d65895d5b17c5A29Ce51",
  "PIP_UNI": "0xe573a75BF4827658F6D600FD26C205a3fe34ee28",
  "MCD_JOIN_UNI_A": "0xb6E6EE050B4a74C8cc1DfdE62cAC8C6d9D8F4CAa",
  "MCD_CLIP_UNI_A": "0xed3D15e390750f0808E64e0Af1F791e6c5b47c2e",
  "MCD_CLIP_CALC_UNI_A": "0x1ee2ecD5149F4b46257a37195994337F4a35E5e8",
  "RENBTC": "0xe3dD56821f8C422849AF4816fE9B3c53c6a2F0Bd",
  "PIP_RENBTC": "0x2f38a1bD385A9B395D01f2Cbf767b4527663edDB",
  "MCD_JOIN_RENBTC_A": "0x12F1F6c7E5fDF1B671CebFBDE974341847d0Caa4",
  "MCD_CLIP_RENBTC_A": "0xEf9EEb37CDB15eaD336440BebC30C4CD37Da1891",
  "MCD_CLIP_CALC_RENBTC_A": "0xF47749299BCCe427cFd9d015D543aEF83D3BD4Da",
  "AAVE": "0x7B339a530Eed72683F56868deDa87BbC64fD9a12",
  "PIP_AAVE": "0xd2d9B1355Ea96567E7D6C7A6945f5c7ec8150Cc9",
  "MCD_JOIN_AAVE_A": "0x9f1Ed3219035e6bDb19E0D95d316c7c39ad302EC",
  "MCD_CLIP_AAVE_A": "0xC8D2d6692981abc7DC5Bf4E345ce3Ce462FA90c9",
  "MCD_CLIP_CALC_AAVE_A": "0x0FdF9CecFF267a49f4e9f67014AFEc873143677D",
  "MATIC": "0x688E1A8830Ea8dd8fe389FA2228997C663b3807A",
  "PIP_MATIC": "0x13594bF4E0C61946936674217c415c6d555Fec50",
  "MCD_JOIN_MATIC_A": "0x4Af8801fbDD5ae4FDe2cbC9F844b09c6777525CE",
  "MCD_CLIP_MATIC_A": "0x75FE5CD0c23894C8424ac835C054aCA92B994445",
  "MCD_CLIP_CALC_MATIC_A": "0x0AB67AA706F1cECD3df457016E822a09bFf18f23",
  "UNIV2DAIETH": "0xB10cf58E08b94480fCb81d341A63295eBb2062C2",
  "PIP_UNIV2DAIETH": "0xED9201cd545F1d2457D2D48981E7832C754959e9",
  "MCD_JOIN_UNIV2DAIETH_A": "0x03f18d97D25c13FecB15aBee143276D3bD2742De",
  "MCD_CLIP_UNIV2DAIETH_A": "0xfcFd4255F67C70Cf5fB534535eBe8152Ba6DC5Cd",
  "MCD_CLIP_CALC_UNIV2DAIETH_A": "0x0Aa53A82182dd60a630A49eCc286b295fEC5Ba98",
  "MIP21_LIQUIDATION_ORACLE": "0x2881c5dF65A8D81e38f7636122aFb456514804CC",
  "RWA001": "0x8F9A8cbBdfb93b72d646c8DEd6B4Fe4D86B315cB",
  "PIP_RWA001": "0x09710C9440e5FF5c473efe61d5a2f14cA05A6752",
  "MCD_JOIN_RWA001_A": "0x029A554f252373e146f76Fa1a7455f73aBF4d38e",
  "RWA001_A_URN": "0x3Ba90D86f7E3218C48b7E0FCa959EcF43d9A30F4",
  "RWA001_A_INPUT_CONDUIT": "0xB944B07EC3B680b2cEA753125667F7663d424DC3",
  "RWA001_A_OUTPUT_CONDUIT": "0xc54fEee07421EAB8000AC8c921c0De9DbfbE780B",
  "RWA002": "0xea8a2f6DC9236edb3f53744f5019a444e24F4379",
  "PIP_RWA002": "0xaD6495E5918C5F66650EDf291C97b31aBaf5Cd7B",
  "MCD_JOIN_RWA002_A": "0x3B3fAD77D6977a19cc7B156143056a3E9C6Ca329",
  "RWA002_A_URN": "0xc615F4188C255445290fB9E6dB5E021fe4CA8ECf",
  "RWA002_A_INPUT_CONDUIT": "0x2CfADbd094a4D650049C53832B15842a3c59Db34",
  "RWA002_A_OUTPUT_CONDUIT": "0x2CfADbd094a4D650049C53832B15842a3c59Db34",
  "RWA003": "0xDBC559F5058E593981C48f4f09fA34323df42d51",
  "PIP_RWA003": "0xA6f7FBeCef878a8B0Fa9AcB214040e962840f209",
  "MCD_JOIN_RWA003_A": "0x4CCc7fED3912A32B6Cf7Db2FdA1554a9FF574099",
  "RWA003_A_URN": "0x993c239179D6858769996bcAb5989ab2DF75913F",
  "RWA003_A_INPUT_CONDUIT": "0x45e17E350279a2f28243983053B634897BA03b64",
  "RWA003_A_OUTPUT_CONDUIT": "0x45e17E350279a2f28243983053B634897BA03b64",
  "RWA004": "0x146b0abaB80a60Bfa3b4fDDb5056bBcFa4f1fec1",
  "PIP_RWA004": "0xF8E535B9C1c230342EAdD1fe2636a872BdC3d8b4",
  "MCD_JOIN_RWA004_A": "0xa92D4082BabF785Ba02f9C419509B7d08f2ef271",
  "RWA004_A_URN": "0xf22C7F5A2AecE1E85263e3cec522BDCD3e392B59",
  "RWA004_A_INPUT_CONDUIT": "0x303dFE04Be5731207c5213FbB54488B3aD9B9FE3",
  "RWA004_A_OUTPUT_CONDUIT": "0x303dFE04Be5731207c5213FbB54488B3aD9B9FE3",
  "RWA005": "0xcB2A48D26970eE7193d66BAc6F1b3090f2E8f82B",
  "PIP_RWA005": "0x0dA25CE01BA1eCBD907694D5237Df0A2740Ce9E7",
  "MCD_JOIN_RWA005_A": "0x1233d0DBb55A4Bb41D711d4B584f8DDB15A2Ff88",
  "RWA005_A_URN": "0xdB9f0700EbBac596CCeF5b14D5e23664Db2A184f",
  "RWA005_A_INPUT_CONDUIT": "0x17E5954Cdd3611Dd84e444F0ed555CC3a06cB319",
  "RWA005_A_OUTPUT_CONDUIT": "0x17E5954Cdd3611Dd84e444F0ed555CC3a06cB319",
  "RWA006": "0x4E65F06574F1630B4fF756C898Fe02f276D53E86",
  "PIP_RWA006": "0x8A4B5c3fDe49486CDEda4D7Fbb4dec6CC6Af8258",
  "MCD_JOIN_RWA006_A": "0x039B74bD0Adc35046B67E88509900D41b9D95430",
  "RWA006_A_URN": "0x6fa6F9C11f5F129f6ECA4B391D9d32038A9666cD",
  "RWA006_A_INPUT_CONDUIT": "0x652A3B3b91459504A8D1d785B0c923A34D638218",
  "RWA006_A_OUTPUT_CONDUIT": "0x652A3B3b91459504A8D1d785B0c923A34D638218",
  "PROXY_PAUSE_ACTIONS": "0x7c52826c1efEAE3199BDBe68e3916CC3eA222E29",
  "PROXY_DEPLOYER": "0xA9fCcB07DD3f774d5b9d02e99DE1a27f47F91189",
  "MCD_FLASH": "0x5aA1323f61D679E52a90120DFDA2ed1A76E4475A",
  "VOTE_DELEGATE_PROXY_FACTORY": "0x1740F3bD55b1900C816A0071F8972C201566e3a3"
}


================================================
FILE: config/mainnet-addresses.json
================================================
{
  "CHANGELOG": "0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F",
  "MULTICALL": "0x5e227AD1969Ea493B43F840cfF78d08a6fc17796",
  "FAUCET": "0x0000000000000000000000000000000000000000",
  "MCD_DEPLOY": "0xbaa65281c2FA2baAcb2cb550BA051525A480D3F4",
  "FLIP_FAB": "0x4ACdbe9dd0d00b36eC2050E805012b8Fc9974f2b",
  "CLIP_FAB": "0x0716F25fBaAae9b63803917b6125c10c313dF663",
  "CALC_FAB": "0xE1820A2780193d74939CcA104087CADd6c1aA13A",
  "LERP_FAB": "0x9175561733D138326FDeA86CdFdF53e92b588276",
  "JOIN_FAB": "0xf1738d22140783707Ca71CB3746e0dc7Bf2b0264",
  "MCD_GOV": "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2",
  "GOV_GUARD": "0x6eEB68B2C7A918f36B78E2DB80dcF279236DDFb8",
  "MCD_ADM": "0x0a3f6849f78076aefaDf113F5BED87720274dDC0",
  "VOTE_PROXY_FACTORY": "0x6FCD258af181B3221073A96dD90D1f7AE7eEc408",
  "VOTE_DELEGATE_PROXY_FACTORY": "0xD897F108670903D1d6070fcf818f9db3615AF272",
  "MCD_VAT": "0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B",
  "MCD_JUG": "0x19c0976f590D67707E62397C87829d896Dc0f1F1",
  "MCD_CAT": "0xa5679C04fc3d9d8b0AaB1F0ab83555b301cA70Ea",
  "MCD_DOG": "0x135954d155898D42C90D2a57824C690e0c7BEf1B",
  "MCD_VOW": "0xA950524441892A31ebddF91d3cEEFa04Bf454466",
  "MCD_JOIN_DAI": "0x9759A6Ac90977b93B58547b4A71c78317f391A28",
  "MCD_FLAP": "0xC4269cC7acDEdC3794b221aA4D9205F564e27f0d",
  "MCD_FLOP": "0xA41B6EF151E06da0e34B009B86E828308986736D",
  "MCD_PAUSE": "0xbE286431454714F511008713973d3B053A2d38f3",
  "MCD_PAUSE_PROXY": "0xBE8E3e3618f7474F8cB1d074A26afFef007E98FB",
  "MCD_GOV_ACTIONS": "0x4F5f0933158569c026d617337614d00Ee6589B6E",
  "MCD_DAI": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
  "MCD_SPOT": "0x65C79fcB50Ca1594B025960e539eD7A9a6D434A3",
  "MCD_POT": "0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7",
  "MCD_END": "0xBB856d1742fD182a90239D7AE85706C2FE4e5922",
  "MCD_ESM": "0x29CfBd381043D00a98fD9904a431015Fef07af2f",
  "PROXY_ACTIONS": "0x82ecD135Dce65Fbc6DbdD0e4237E0AF93FFD5038",
  "PROXY_ACTIONS_END": "0x7AfF9FC9faD225e3c88cDA06BC56d8Aca774bC57",
  "PROXY_ACTIONS_DSR": "0x07ee93aEEa0a36FfF2A9B95dd22Bd6049EE54f26",
  "CDP_MANAGER": "0x5ef30b9986345249bc32d8928B7ee64DE9435E39",
  "DSR_MANAGER": "0x373238337Bfe1146fb49989fc222523f83081dDb",
  "GET_CDPS": "0x36a724Bd100c39f0Ea4D3A20F7097eE01A8Ff573",
  "ILK_REGISTRY": "0x5a464C28D19848f44199D003BeF5ecc87d090F87",
  "OSM_MOM": "0x76416A4d5190d071bfed309861527431304aA14f",
  "FLIPPER_MOM": "0xc4bE7F74Ee3743bDEd8E0fA218ee5cf06397f472",
  "CLIPPER_MOM": "0x79FBDF16b366DFb14F66cE4Ac2815Ca7296405A0",
  "MCD_IAM_AUTO_LINE": "0xC7Bdd1F2B16447dcf3dE045C4a039A60EC2f0ba3",
  "MCD_FLASH": "0x1EB4CF3A948E7D72A198fe073cCb8C7a948cD853",
  "PROXY_FACTORY": "0xA26e15C895EFc0616177B7c1e7270A4C7D51C997",
  "PROXY_REGISTRY": "0x4678f0a6958e4D2Bc4F1BAF7Bc52E8F3564f3fE4",
  "MCD_VEST_DAI": "0x2Cc583c0AaCDaC9e23CB601fDA8F1A0c56Cdcb71",
  "MCD_VEST_MKR": "0x0fC8D4f2151453ca0cA56f07359049c8f07997Bd",
  "MCD_VEST_MKR_TREASURY": "0x6D635c8d08a1eA2F1687a5E46b666949c977B7dd",
  "ETH": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
  "PIP_ETH": "0x81FE72B5A8d1A857d176C3E7d5Bd2679A9B85763",
  "MCD_JOIN_ETH_A": "0x2F0b23f53734252Bda2277357e97e1517d6B042A",
  "MCD_CLIP_ETH_A": "0xc67963a226eddd77B91aD8c421630A1b0AdFF270",
  "MCD_CLIP_CALC_ETH_A": "0x7d9f92DAa9254Bbd1f479DBE5058f74C2381A898",
  "MCD_JOIN_ETH_B": "0x08638eF1A205bE6762A8b935F5da9b700Cf7322c",
  "MCD_CLIP_ETH_B": "0x71eb894330e8a4b96b8d6056962e7F116F50e06F",
  "MCD_CLIP_CALC_ETH_B": "0x19E26067c4a69B9534adf97ED8f986c49179dE18",
  "MCD_JOIN_ETH_C": "0xF04a5cC80B1E94C69B48f5ee68a08CD2F09A7c3E",
  "MCD_CLIP_ETH_C": "0xc2b12567523e3f3CBd9931492b91fe65b240bc47",
  "MCD_CLIP_CALC_ETH_C": "0x1c4fC274D12b2e1BBDF97795193D3148fCDa6108",
  "BAT": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF",
  "PIP_BAT": "0xB4eb54AF9Cc7882DF0121d26c5b97E802915ABe6",
  "MCD_JOIN_BAT_A": "0x3D0B1912B66114d4096F48A8CEe3A56C231772cA",
  "MCD_CLIP_BAT_A": "0x3D22e6f643e2F4c563fD9db22b229Cbb0Cd570fb",
  "MCD_CLIP_CALC_BAT_A": "0x2e118153D304a0d9C5838D5FCb70CEfCbEc81DC2",
  "USDC": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  "PIP_USDC": "0x77b68899b99b686F415d074278a9a16b336085A0",
  "MCD_JOIN_USDC_A": "0xA191e578a6736167326d05c119CE0c90849E84B7",
  "MCD_CLIP_USDC_A": "0x046b1A5718da6A226D912cFd306BA19980772908",
  "MCD_CLIP_CALC_USDC_A": "0x0FCa4ba0B80123b5d22dD3C8BF595F3E561d594D",
  "MCD_JOIN_USDC_B": "0x2600004fd1585f7270756DDc88aD9cfA10dD0428",
  "MCD_CLIP_USDC_B": "0x5590F23358Fe17361d7E4E4f91219145D8cCfCb3",
  "MCD_CLIP_CALC_USDC_B": "0xD6FE411284b92d309F79e502Dd905D7A3b02F561",
  "WBTC": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
  "PIP_WBTC": "0xf185d0682d50819263941e5f4EacC763CC5C6C42",
  "MCD_JOIN_WBTC_A": "0xBF72Da2Bd84c5170618Fbe5914B0ECA9638d5eb5",
  "MCD_CLIP_WBTC_A": "0x0227b54AdbFAEec5f1eD1dFa11f54dcff9076e2C",
  "MCD_CLIP_CALC_WBTC_A": "0x5f4CEa97ca1030C6Bd38429c8a0De7Cd4981C70A",
  "MCD_JOIN_WBTC_B": "0xfA8c996e158B80D77FbD0082BB437556A65B96E0",
  "MCD_CLIP_WBTC_B": "0xe30663C6f83A06eDeE6273d72274AE24f1084a22",
  "MCD_CLIP_CALC_WBTC_B": "0xeb911E99D7ADD1350DC39d84D60835BA9B287D96",
  "MCD_JOIN_WBTC_C": "0x7f62f9592b823331E012D3c5DdF2A7714CfB9de2",
  "MCD_CLIP_WBTC_C": "0x39F29773Dcb94A32529d0612C6706C49622161D1",
  "MCD_CLIP_CALC_WBTC_C": "0x4fa2A328E7f69D023fE83454133c273bF5ACD435",
  "TUSD": "0x0000000000085d4780B73119b644AE5ecd22b376",
  "PIP_TUSD": "0xeE13831ca96d191B688A670D47173694ba98f1e5",
  "MCD_JOIN_TUSD_A": "0x4454aF7C8bb9463203b66C816220D41ED7837f44",
  "MCD_CLIP_TUSD_A": "0x0F6f88f8A4b918584E3539182793a0C276097f44",
  "MCD_CLIP_CALC_TUSD_A": "0x059acdf311E38aAF77139638228d393Ff27639bF",
  "ZRX": "0xE41d2489571d322189246DaFA5ebDe1F4699F498",
  "PIP_ZRX": "0x7382c066801E7Acb2299aC8562847B9883f5CD3c",
  "MCD_JOIN_ZRX_A": "0xc7e8Cd72BDEe38865b4F5615956eF47ce1a7e5D0",
  "MCD_CLIP_ZRX_A": "0xdc90d461E148552387f3aB3EBEE0Bdc58Aa16375",
  "MCD_CLIP_CALC_ZRX_A": "0xebe5e9D77b9DBBA8907A197f4c2aB00A81fb0C4e",
  "KNC": "0xdd974D5C2e2928deA5F71b9825b8b646686BD200",
  "PIP_KNC": "0xf36B79BD4C0904A5F350F1e4f776B81208c13069",
  "MCD_JOIN_KNC_A": "0x475F1a89C1ED844A08E8f6C50A00228b5E59E4A9",
  "MCD_CLIP_KNC_A": "0x006Aa3eB5E666D8E006aa647D4afAB212555Ddea",
  "MCD_CLIP_CALC_KNC_A": "0x82c41e2ADE28C066a5D3A1E3f5B444a4075C1584",
  "MANA": "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942",
  "PIP_MANA": "0x8067259EA630601f319FccE477977E55C6078C13",
  "MCD_JOIN_MANA_A": "0xA6EA3b9C04b8a38Ff5e224E7c3D6937ca44C0ef9",
  "MCD_CLIP_MANA_A": "0xF5C8176E1eB0915359E46DEd16E52C071Bb435c0",
  "MCD_CLIP_CALC_MANA_A": "0xABbCd14FeDbb2D39038327055D9e615e178Fd64D",
  "USDT": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
  "PIP_USDT": "0x7a5918670B0C390aD25f7beE908c1ACc2d314A3C",
  "MCD_JOIN_USDT_A": "0x0Ac6A1D74E84C2dF9063bDDc31699FF2a2BB22A2",
  "MCD_CLIP_USDT_A": "0xFC9D6Dd08BEE324A5A8B557d2854B9c36c2AeC5d",
  "MCD_CLIP_CALC_USDT_A": "0x1Cf3DE6D570291CDB88229E70037d1705d5be748",
  "PAXUSD": "0x8E870D67F660D95d5be530380D0eC0bd388289E1",
  "PAX": "0x8E870D67F660D95d5be530380D0eC0bd388289E1",
  "PIP_PAXUSD": "0x043B963E1B2214eC90046167Ea29C2c8bDD7c0eC",
  "PIP_PAX": "0x043B963E1B2214eC90046167Ea29C2c8bDD7c0eC",
  "MCD_JOIN_PAXUSD_A": "0x7e62B7E279DFC78DEB656E34D6a435cC08a44666",
  "MCD_CLIP_PAXUSD_A": "0xBCb396Cd139D1116BD89562B49b9D1d6c25378B0",
  "MCD_CLIP_CALC_PAXUSD_A": "0xAB98De83840b8367046383D2Adef9959E130923e",
  "COMP": "0xc00e94Cb662C3520282E6f5717214004A7f26888",
  "PIP_COMP": "0xBED0879953E633135a48a157718Aa791AC0108E4",
  "MCD_JOIN_COMP_A": "0xBEa7cDfB4b49EC154Ae1c0D731E4DC773A3265aA",
  "MCD_CLIP_COMP_A": "0x2Bb690931407DCA7ecE84753EA931ffd304f0F38",
  "MCD_CLIP_CALC_COMP_A": "0x1f546560EAa70985d962f1562B65D4B182341a63",
  "LRC": "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD",
  "PIP_LRC": "0x9eb923339c24c40Bef2f4AF4961742AA7C23EF3a",
  "MCD_JOIN_LRC_A": "0x6C186404A7A238D3d6027C0299D1822c1cf5d8f1",
  "MCD_CLIP_LRC_A": "0x81C5CDf4817DBf75C7F08B8A1cdaB05c9B3f70F7",
  "MCD_CLIP_CALC_LRC_A": "0x6856CCA4c881CAf29B6563bA046C7Bb73121fb9d",
  "LINK": "0x514910771AF9Ca656af840dff83E8264EcF986CA",
  "PIP_LINK": "0x9B0C694C6939b5EA9584e9b61C7815E8d97D9cC7",
  "MCD_JOIN_LINK_A": "0xdFccAf8fDbD2F4805C174f856a317765B49E4a50",
  "MCD_CLIP_LINK_A": "0x832Dd5f17B30078a5E46Fdb8130A68cBc4a74dC0",
  "MCD_CLIP_CALC_LINK_A": "0x7B1696677107E48B152e9Bf400293e98B7D86Eb1",
  "BAL": "0xba100000625a3754423978a60c9317c58a424e3D",
  "PIP_BAL": "0x3ff860c0F28D69F392543A16A397D0dAe85D16dE",
  "MCD_JOIN_BAL_A": "0x4a03Aa7fb3973d8f0221B466EefB53D0aC195f55",
  "MCD_CLIP_BAL_A": "0x6AAc067bb903E633A422dE7BE9355E62B3CE0378",
  "MCD_CLIP_CALC_BAL_A": "0x79564a41508DA86721eDaDac07A590b5A51B2c01",
  "YFI": "0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e",
  "PIP_YFI": "0x5F122465bCf86F45922036970Be6DD7F58820214",
  "MCD_JOIN_YFI_A": "0x3ff33d9162aD47660083D7DC4bC02Fb231c81677",
  "MCD_CLIP_YFI_A": "0x9daCc11dcD0aa13386D295eAeeBBd38130897E6f",
  "MCD_CLIP_CALC_YFI_A": "0x1f206d7916Fd3B1b5B0Ce53d5Cab11FCebc124DA",
  "GUSD": "0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd",
  "PIP_GUSD": "0xf45Ae69CcA1b9B043dAE2C83A5B65Bc605BEc5F5",
  "MCD_JOIN_GUSD_A": "0xe29A14bcDeA40d83675aa43B72dF07f649738C8b",
  "MCD_CLIP_GUSD_A": "0xa47D68b9dB0A0361284fA04BA40623fcBd1a263E",
  "MCD_CLIP_CALC_GUSD_A": "0xF7e80359Cb9C4E6D178E6689eD8A6A6f91060747",
  "UNI": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
  "PIP_UNI": "0xf363c7e351C96b910b92b45d34190650df4aE8e7",
  "MCD_JOIN_UNI_A": "0x3BC3A58b4FC1CbE7e98bB4aB7c99535e8bA9b8F1",
  "MCD_CLIP_UNI_A": "0x3713F83Ee6D138Ce191294C131148176015bC29a",
  "MCD_CLIP_CALC_UNI_A": "0xeA7FE6610e6708E2AFFA202948cA19ace3F580AE",
  "RENBTC": "0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D",
  "PIP_RENBTC": "0xf185d0682d50819263941e5f4EacC763CC5C6C42",
  "MCD_JOIN_RENBTC_A": "0xFD5608515A47C37afbA68960c1916b79af9491D0",
  "MCD_CLIP_RENBTC_A": "0x834719BEa8da68c46484E001143bDDe29370a6A3",
  "MCD_CLIP_CALC_RENBTC_A": "0xcC89F368aad8D424d3e759c1525065e56019a0F4",
  "AAVE": "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9",
  "PIP_AAVE": "0x8Df8f06DC2dE0434db40dcBb32a82A104218754c",
  "MCD_JOIN_AAVE_A": "0x24e459F61cEAa7b1cE70Dbaea938940A7c5aD46e",
  "MCD_CLIP_AAVE_A": "0x8723b74F598DE2ea49747de5896f9034CC09349e",
  "MCD_CLIP_CALC_AAVE_A": "0x76024a8EfFCFE270e089964a562Ece6ea5f3a14C",
  "MATIC": "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0",
  "PIP_MATIC": "0x8874964279302e6d4e523Fb1789981C39a1034Ba",
  "MCD_JOIN_MATIC_A": "0x885f16e177d45fC9e7C87e1DA9fd47A9cfcE8E13",
  "MCD_CLIP_MATIC_A": "0x29342F530ed6120BDB219D602DaFD584676293d1",
  "MCD_CLIP_CALC_MATIC_A": "0xdF8C347B06a31c6ED11f8213C2366348BFea68dB",
  "STETH": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
  "WSTETH": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
  "PIP_WSTETH": "0xFe7a2aC0B945f12089aEEB6eCebf4F384D9f043F",
  "MCD_JOIN_WSTETH_A": "0x10CD5fbe1b404B7E19Ef964B63939907bdaf42E2",
  "MCD_CLIP_WSTETH_A": "0x49A33A28C4C7D9576ab28898F4C9ac7e52EA457A",
  "MCD_CLIP_CALC_WSTETH_A": "0x15282b886675cc1Ce04590148f456428E87eaf13",
  "RETH":"0xae78736Cd615f374D3085123A210448E74Fc6393",
  "PIP_RETH":"0xeE7F0b350aA119b3d05DC733a4621a81972f7D47",
  "MCD_JOIN_RETH_A":"0xC6424e862f1462281B0a5FAc078e4b63006bDEBF",
  "MCD_CLIP_CALC_RETH_A":"0xc59B62AFC96cf9737F717B5e5815070C0f154396",
  "MCD_CLIP_RETH_A":"0x27CA5E525ea473eD52Ea9423CD08cCc081d96a98",
  "GNO":"0x6810e776880C02933D47DB1b9fc05908e5386b96",
  "PIP_GNO":"0xd800ca44fFABecd159c7889c3bf64a217361AEc8",
  "MCD_JOIN_GNO_A":"0x7bD3f01e24E0f0838788bC8f573CEA43A80CaBB5",
  "MCD_CLIP_CALC_GNO_A":"0x17b6D0e4237ea7F880aF5F58257cd232a04171D9",
  "MCD_CLIP_GNO_A":"0xd9e758bd239e5d568f44D0A748633f6a8d52CBbb",
  "UNIV2DAIETH": "0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11",
  "PIP_UNIV2DAIETH": "0xFc8137E1a45BAF0030563EC4F0F851bd36a85b7D",
  "MCD_JOIN_UNIV2DAIETH_A": "0x2502F65D77cA13f183850b5f9272270454094A08",
  "MCD_CLIP_UNIV2DAIETH_A": "0x9F6981bA5c77211A34B76c6385c0f6FA10414035",
  "MCD_CLIP_CALC_UNIV2DAIETH_A": "0xf738C272D648Cc4565EaFb43c0C5B35BbA3bf29d",
  "UNIV2WBTCETH": "0xBb2b8038a1640196FbE3e38816F3e67Cba72D940",
  "PIP_UNIV2WBTCETH": "0x8400D2EDb8B97f780356Ef602b1BdBc082c2aD07",
  "MCD_JOIN_UNIV2WBTCETH_A": "0xDc26C9b7a8fe4F5dF648E314eC3E6Dc3694e6Dd2",
  "MCD_CLIP_UNIV2WBTCETH_A": "0xb15afaB996904170f87a64Fe42db0b64a6F75d24",
  "MCD_CLIP_CALC_UNIV2WBTCETH_A": "0xC94ee71e909DbE08d63aA9e6EFbc9976751601B4",
  "UNIV2USDCETH": "0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc",
  "PIP_UNIV2USDCETH": "0xf751f24DD9cfAd885984D1bA68860F558D21E52A",
  "MCD_JOIN_UNIV2USDCETH_A": "0x03Ae53B33FeeAc1222C3f372f32D37Ba95f0F099",
  "MCD_CLIP_UNIV2USDCETH_A": "0x93AE03815BAF1F19d7F18D9116E4b637cc32A131",
  "MCD_CLIP_CALC_UNIV2USDCETH_A": "0x022ff40643e8b94C43f0a1E54f51EF6D070AcbC4",
  "UNIV2DAIUSDC": "0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5",
  "PIP_UNIV2DAIUSDC": "0x25D03C2C928ADE19ff9f4FFECc07d991d0df054B",
  "MCD_JOIN_UNIV2DAIUSDC_A": "0xA81598667AC561986b70ae11bBE2dd5348ed4327",
  "MCD_CLIP_UNIV2DAIUSDC_A": "0x9B3310708af333f6F379FA42a5d09CBAA10ab309",
  "MCD_CLIP_CALC_UNIV2DAIUSDC_A": "0xbEF2ab2aA5CC780A03bccf22AD3320c8CF35af6A",
  "UNIV2ETHUSDT": "0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852",
  "PIP_UNIV2ETHUSDT": "0x5f6dD5B421B8d92c59dC6D907C9271b1DBFE3016",
  "MCD_JOIN_UNIV2ETHUSDT_A": "0x4aAD139a88D2dd5e7410b408593208523a3a891d",
  "MCD_CLIP_UNIV2ETHUSDT_A": "0x2aC4C9b49051275AcB4C43Ec973082388D015D48",
  "MCD_CLIP_CALC_UNIV2ETHUSDT_A": "0xA475582E3D6Ec35091EaE81da3b423C1B27fa029",
  "UNIV2LINKETH": "0xa2107FA5B38d9bbd2C461D6EDf11B11A50F6b974",
  "PIP_UNIV2LINKETH": "0xd7d31e62AE5bfC3bfaa24Eda33e8c32D31a1746F",
  "MCD_JOIN_UNIV2LINKETH_A": "0xDae88bDe1FB38cF39B6A02b595930A3449e593A6",
  "MCD_CLIP_UNIV2LINKETH_A": "0x6aa0520354d1b84e1C6ABFE64a708939529b619e",
  "MCD_CLIP_CALC_UNIV2LINKETH_A": "0x8aCeC2d937a4A4cAF42565aFbbb05ac242134F14",
  "UNIV2UNIETH": "0xd3d2E2692501A5c9Ca623199D38826e513033a17",
  "PIP_UNIV2UNIETH": "0x8462A88f50122782Cc96108F476deDB12248f931",
  "MCD_JOIN_UNIV2UNIETH_A": "0xf11a98339FE1CdE648e8D1463310CE3ccC3d7cC1",
  "MCD_CLIP_UNIV2UNIETH_A": "0xb0ece6F5542A4577E2f1Be491A937Ccbbec8479e",
  "MCD_CLIP_CALC_UNIV2UNIETH_A": "0xad609Ed16157014EF955C94553E40e94A09049f0",
  "UNIV2WBTCDAI": "0x231B7589426Ffe1b75405526fC32aC09D44364c4",
  "PIP_UNIV2WBTCDAI": "0x5bB72127a196392cf4aC00Cf57aB278394d24e55",
  "MCD_JOIN_UNIV2WBTCDAI_A": "0xD40798267795Cbf3aeEA8E9F8DCbdBA9b5281fcC",
  "MCD_CLIP_UNIV2WBTCDAI_A": "0x4fC53a57262B87ABDa61d6d0DB2bE7E9BE68F6b8",
  "MCD_CLIP_CALC_UNIV2WBTCDAI_A": "0x863AEa7D2c4BF2B5Aa191B057240b6Dc29F532eB",
  "UNIV2AAVEETH": "0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f",
  "PIP_UNIV2AAVEETH": "0x32d8416e8538Ac36272c44b0cd962cD7E0198489",
  "MCD_JOIN_UNIV2AAVEETH_A": "0x42AFd448Df7d96291551f1eFE1A590101afB1DfF",
  "MCD_CLIP_UNIV2AAVEETH_A": "0x854b252BA15eaFA4d1609D3B98e00cc10084Ec55",
  "MCD_CLIP_CALC_UNIV2AAVEETH_A": "0x5396e541E1F648EC03faf338389045F1D7691960",
  "UNIV2DAIUSDT": "0xB20bd5D04BE54f870D5C0d3cA85d82b34B836405",
  "PIP_UNIV2DAIUSDT": "0x9A1CD705dc7ac64B50777BcEcA3529E58B1292F1",
  "MCD_JOIN_UNIV2DAIUSDT_A": "0xAf034D882169328CAf43b823a4083dABC7EEE0F4",
  "MCD_CLIP_UNIV2DAIUSDT_A": "0xe4B82Be84391b9e7c56a1fC821f47569B364dd4a",
  "MCD_CLIP_CALC_UNIV2DAIUSDT_A": "0x4E88cE740F6bEa31C2b14134F6C5eB2a63104fcF",
  "GUNIV3DAIUSDC1": "0xAbDDAfB225e10B90D798bB8A886238Fb835e2053",
  "PIP_GUNIV3DAIUSDC1": "0x7F6d78CC0040c87943a0e0c140De3F77a273bd58",
  "MCD_JOIN_GUNIV3DAIUSDC1_A": "0xbFD445A97e7459b0eBb34cfbd3245750Dba4d7a4",
  "MCD_CLIP_GUNIV3DAIUSDC1_A": "0x5048c5Cd3102026472f8914557A1FD35c8Dc6c9e",
  "MCD_CLIP_CALC_GUNIV3DAIUSDC1_A": "0x25B17065b94e3fDcD97d94A2DA29E7F77105aDd7",
  "GUNIV3DAIUSDC2": "0x50379f632ca68D36E50cfBC8F78fe16bd1499d1e",
  "PIP_GUNIV3DAIUSDC2": "0xcCBa43231aC6eceBd1278B90c3a44711a00F4e93",
  "MCD_JOIN_GUNIV3DAIUSDC2_A": "0xA7e4dDde3cBcEf122851A7C8F7A55f23c0Daf335",
  "MCD_CLIP_GUNIV3DAIUSDC2_A": "0xB55da3d3100C4eBF9De755b6DdC24BF209f6cc06",
  "MCD_CLIP_CALC_GUNIV3DAIUSDC2_A": "0xef051Ca2A2d809ba47ee0FC8caaEd06E3D832225",
  "CRVV1ETHSTETH": "0x06325440D014e39736583c165C2963BA99fAf14E",
  "PIP_CRVV1ETHSTETH": "0xEa508F82728927454bd3ce853171b0e2705880D4",
  "MCD_JOIN_CRVV1ETHSTETH_A": "0x82d8bfdb61404c796385f251654f6d7e92092b5d",
  "MCD_CLIP_CRVV1ETHSTETH_A": "0x1926862f899410bfc19fefb8a3c69c7aed22463a",
  "MCD_CLIP_CALC_CRVV1ETHSTETH_A": "0x8a4780acabadcae1a297b2eae5deebd7d50deeb8",
  "MIP21_LIQUIDATION_ORACLE": "0x88f88Bb9E66241B73B84f3A6E197FbBa487b1E30",
  "RWA001": "0x10b2aA5D77Aa6484886d8e244f0686aB319a270d",
  "PIP_RWA001": "0x76A9f30B45F4ebFD60Ce8a1c6e963b1605f7cB6d",
  "MCD_JOIN_RWA001_A": "0x476b81c12Dc71EDfad1F64B9E07CaA60F4b156E2",
  "RWA001_A_URN": "0xa3342059BcDcFA57a13b12a35eD4BBE59B873005",
  "RWA001_A_INPUT_CONDUIT": "0x486C85e2bb9801d14f6A8fdb78F5108a0fd932f2",
  "RWA001_A_OUTPUT_CONDUIT": "0xb3eFb912e1cbC0B26FC17388Dd433Cecd2206C3d",
  "RWA002": "0xAAA760c2027817169D7C8DB0DC61A2fb4c19AC23",
  "PIP_RWA002": "0xd2473237E20Bd52F8E7cE0FD79403A6a82fbAEC8",
  "MCD_JOIN_RWA002_A": "0xe72C7e90bc26c11d45dBeE736F0acf57fC5B7152",
  "RWA002_A_URN": "0x225B3da5BE762Ee52B182157E67BeA0b31968163",
  "RWA002_A_INPUT_CONDUIT": "0x2474F297214E5d96Ba4C81986A9F0e5C260f445D",
  "RWA002_A_OUTPUT_CONDUIT": "0x2474F297214E5d96Ba4C81986A9F0e5C260f445D",
  "RWA003": "0x07F0A80aD7AeB7BfB7f139EA71B3C8f7E17156B9",
  "PIP_RWA003": "0xDeF7E88447F7D129420FC881B2a854ABB52B73B8",
  "MCD_JOIN_RWA003_A": "0x1Fe789BBac5b141bdD795A3Bc5E12Af29dDB4b86",
  "RWA003_A_URN": "0x7bF825718e7C388c3be16CFe9982539A7455540F",
  "RWA003_A_INPUT_CONDUIT": "0x2A9798c6F165B6D60Cfb923Fe5BFD6f338695D9B",
  "RWA003_A_OUTPUT_CONDUIT": "0x2A9798c6F165B6D60Cfb923Fe5BFD6f338695D9B",
  "RWA004": "0x873F2101047A62F84456E3B2B13df2287925D3F9",
  "PIP_RWA004": "0x5eEE1F3d14850332A75324514CcbD2DBC8Bbc566",
  "MCD_JOIN_RWA004_A": "0xD50a8e9369140539D1c2D113c4dC1e659c6242eB",
  "RWA004_A_URN": "0xeF1699548717aa4Cf47aD738316280b56814C821",
  "RWA004_A_INPUT_CONDUIT": "0xe1ed3F588A98bF8a3744f4BF74Fd8540e81AdE3f",
  "RWA004_A_OUTPUT_CONDUIT": "0xe1ed3F588A98bF8a3744f4BF74Fd8540e81AdE3f",
  "RWA005": "0x6DB236515E90fC831D146f5829407746EDdc5296",
  "PIP_RWA005": "0x8E6039C558738eb136833aB50271ae065c700d2B",
  "MCD_JOIN_RWA005_A": "0xA4fD373b93aD8e054970A3d6cd4Fd4C31D08192e",
  "RWA005_A_URN": "0xc40907545C57dB30F01a1c2acB242C7c7ACB2B90",
  "RWA005_A_INPUT_CONDUIT": "0x5b702e1fEF3F556cbe219eE697D7f170A236cc66",
  "RWA005_A_OUTPUT_CONDUIT": "0x5b702e1fEF3F556cbe219eE697D7f170A236cc66",
  "RWA006": "0x4EE03cfBF6E784c462839f5954d60f7C2B60b113",
  "PIP_RWA006": "0xB8AeCF04Fdf22Ef6C0c6b6536896e1F2870C41D3",
  "MCD_JOIN_RWA006_A": "0x5E11E34b6745FeBa9449Ae53c185413d6EdC66BE",
  "RWA006_A_URN": "0x0C185bf5388DdfDB288F4D875265d456D18FD9Cb",
  "RWA006_A_INPUT_CONDUIT": "0x8Fe38D1E4293181273E2e323e4c16e0D1d4861e3",
  "RWA006_A_OUTPUT_CONDUIT": "0x8Fe38D1E4293181273E2e323e4c16e0D1d4861e3",
  "PROXY_PAUSE_ACTIONS": "0x6bda13D43B7EDd6CAfE1f70fB98b5d40f61A1370",
  "PROXY_DEPLOYER": "0x1b93556AB8dcCEF01Cd7823C617a6d340f53Fb58",
  "OPTIMISM_DAI_BRIDGE": "0x10E6593CDda8c58a1d0f14C5164B376352a55f2F",
  "OPTIMISM_ESCROW": "0x467194771dAe2967Aef3ECbEDD3Bf9a310C76C65",
  "OPTIMISM_GOV_RELAY": "0x09B354CDA89203BB7B3131CC728dFa06ab09Ae2F",
  "ARBITRUM_DAI_BRIDGE": "0xD3B5b60020504bc3489D6949d545893982BA3011",
  "ARBITRUM_ESCROW": "0xA10c7CE4b876998858b1a9E12b10092229539400",
  "ARBITRUM_GOV_RELAY": "0x9ba25c289e351779E0D481Ba37489317c34A899d"
}


================================================
FILE: config/testnet-addresses.json
================================================
{
  "DEPLOYER": "0x00a329c0648769A73afAc7F9381E08FB43dBEA72",
  "MULTICALL": "0x492934308E98b590A626666B703A6dDf2120e85e",
  "FAUCET": "0x0A64DF94bc0E039474DB42bb52FEca0c1d540402",
  "MCD_DEPLOY": "0xd29915F1A3fF9846fE5D8d9d2C954de21932AF7F",
  "MCD_GOV": "0x1FD8397e8108ada12eC07976D92F773364ba46e7",
  "GOV_GUARD": "0x39a812a6aA4C475b6562B73Bf0584eb3655e8D6C",
  "MCD_IOU": "0xDfBc5fbEaa41bD1cd15F9d6b77265DBc3CB2A677",
  "MCD_ADM": "0x8c39d4833812A7516BaCD455dA7F97f0a8C11B05",
  "VOTE_PROXY_FACTORY": "0x2dC383E93ec3DB735777a3E9ae69E2aD81edaF03",
  "MCD_VAT": "0x3D72e5B28FbA05Bd4090A2A587Bb3eCC899f33b2",
  "MCD_JUG": "0x77a371Ed06fbA2D93D05C5bDE6d8eC58b3a35fbd",
  "MCD_CAT": "0x31865076D1E28ad4eA06D5Db7aAa4AAF225f1Fb5",
  "MCD_DOG": "0xd9b3B2429F1b301156Bf3103419ef6B78E888386",
  "MCD_VOW": "0xA2F9C8C13118c88f14501cDCB2b52Af3751622ae",
  "MCD_JOIN_DAI": "0x7f8241b7250c5C5368788543E4dA2F9A919E9F02",
  "MCD_FLAP": "0xB5054202380d093A02916e0137d75b54D6182A23",
  "MCD_FLOP": "0xd57D9931b305f1bc1622B97c8Cc6747E4A9254a0",
  "MCD_PAUSE": "0x967aE1FB90aA36C7d3B16B5328504F542495D952",
  "MCD_PAUSE_PROXY": "0x3689de8F568e4A59254eE7eaB1A37d87044f52Da",
  "MCD_GOV_ACTIONS": "0x2287909BB95FA078C73CC2d5a5AF6fE1244b0911",
  "MCD_DAI": "0x8A1567046e610Fec30F120BB70Df94B50561C1d3",
  "MCD_SPOT": "0x5422Ee4e22603E336905CDC9D59aE3F0012fe4c8",
  "MCD_POT": "0xe51e9A4D22b7451c0232508455195E7c0a6e0f19",
  "MCD_END": "0x27547dE5f11122283825Adf97FB98eF301f5F73c",
  "MCD_ESM": "0x8a606fD18B9f0CA3Cf480e70639c58EAa98d7389",
  "PROXY_ACTIONS": "0x84617303947304444Ceb641582c024f277BBF4Ff",
  "PROXY_ACTIONS_END": "0x78c362A5690447EA2BBC3E8008502efD13936F79",
  "PROXY_ACTIONS_DSR": "0x277aD07109FE52a742B808a3E6765Ee1Ad0e7Ad2",
  "CDP_MANAGER": "0x79a8FC3D98Fc84c9BC2B3a737EA992321a1b86A3",
  "DSR_MANAGER": "0x0Faf2F31Ab165B55F42E55c8065c0EC7170A0d45",
  "GET_CDPS": "0x4f05AfbC371854D027263e756487BDefD099178f",
  "ILK_REGISTRY": "0x8e23974b151827f0E8151aC526C4c4c974c06A90",
  "OSM_MOM": "0x96724aa934979936aE5c3Afda1599b5ed61252ce",
  "FLIPPER_MOM": "0xcbfD09D76140D01E573b452bB984d82589571fC2",
  "CLIPPER_MOM": "0x9BB69befBAA567a7EaEE33b671756596517338F4",
  "MCD_IAM_AUTO_LINE": "0x01E354A7eF79962DbB690705e46bd54c1C855E80",
  "PROXY_FACTORY": "0x3DD0864668C36D27B53a98137764c99F9FD5B7B2",
  "PROXY_REGISTRY": "0x26C8d09E5C0B423E2827844c770F61c9af2870E7",
  "ETH": "0xEddA486ddB7eaa8f9FEce8c682EFD40f535b3Ad5",
  "VAL_ETH": "0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84",
  "MCD_JOIN_ETH_A": "0x9119B5d8b735E4cEbaE7386AF6cD2B863c7d35A8",
  "MCD_FLIP_ETH_A": "0x0BD7632aF5F7020575e59E80ABbca739035Ac0EC",
  "MCD_JOIN_ETH_B": "0xe2dD18a6000030F30ecB1237B15605533f814c59",
  "MCD_CLIP_ETH_B": "0x3f2603979a4A185acE9B9c941193704FfBD24F4A",
  "MCD_CLIP_CALC_ETH_B": "0x8cabea65F0140962A7D7Fe9f31a265a2B19Dc305",
  "MCD_JOIN_ETH_C": "0x9FdC3bBD89ae1fB19054241644EF3dfbdcA85544",
  "MCD_FLIP_ETH_C": "0xB0b7Db244994E9B922998f49b7ae61956314CA35",
  "BAT": "0x39b4C0A63c4c16DD1816D104F2C18a296Dbd4e70",
  "VAL_BAT": "0x62d69f6867A0A084C6d313943dC22023Bc263691",
  "MCD_JOIN_BAT_A": "0xA616aD7D4562dCD9208425Af4038defD0a9057B0",
  "MCD_FLIP_BAT_A": "0xB36901dB56E2fb44862a7D0eAE9F5Cf9a7E449bD",
  "USDC": "0x32Ee2bF1267253f76298D4199095B9C6b5A389c0",
  "VAL_USDC": "0xee35211C4D9126D520bBfeaf3cFee5FE7B86F221",
  "MCD_JOIN_USDC_A": "0x59ea98A4b40B72140b7dc93c29c098AE607Ce20D",
  "MCD_FLIP_USDC_A": "0xE8a124764cCcb7Ee3E8e320aAaA841Ea249197D4",
  "MCD_JOIN_USDC_B": "0xaD1Bf7D34Fa48f7Cf7CA1CE3c7408f9151DF2745",
  "MCD_FLIP_USDC_B": "0xC8055bC4415Ac354fA6EFbC3bcf57d5cBcc072ed",
  "TUSD": "0xB014e899ddb9a55af72fE09E8570E700A5167b6d",
  "VAL_TUSD": "0x7C276DcAab99BD16163c1bcce671CaD6A1ec0945",
  "MCD_JOIN_TUSD_A": "0xAFB95880bc835B6Eeb041ce57D570D013360beC6",
  "MCD_FLIP_TUSD_A": "0x6b0f809E52218192AbAf32C9C74F31229E07B626",
  "WBTC": "0x123010c0Fe7D4d7420f309431bb95060393fe3B7",
  "VAL_WBTC": "0x3f85D0b6119B38b7E6B119F7550290fec4BE0e3c",
  "MCD_JOIN_WBTC_A": "0xf4C33a989bD0C9e9268c5bfCbCE2C8501B9dBa25",
  "MCD_FLIP_WBTC_A": "0x53781B6DC81F5b90421371172c1b06e384858e44",
  "GUSD": "0x0363Ef677c78bd8C8302DB33be2F6629E33E72Fe",
  "VAL_GUSD": "0xd5F051401ca478B34C80D0B5A119e437Dc6D9df5",
  "MCD_JOIN_GUSD_A": "0x01C957395029E9aCCbCb25a6Ab72C618252CACf9",
  "MCD_FLIP_GUSD_A": "0x334490acE32D96808B104A1f8723cFAB5881DE46",
  "PROXY_PAUSE_ACTIONS": "0x23263d4ebB1190A483A84e90B9a6Dd8720979284",
  "PROXY_DEPLOYER": "0x30c8860f6a38819B59E1255A499A10bCBF4Ee747"
}

================================================
FILE: docker-compose.yml
================================================
version: "3.2"
services:
  parity:
    image: makerdao/testchain-pymaker:unit-testing-2.0.0
    container_name: parity-pymaker-test
    ports:
      - "8545:8545"
      - "8546:8546"
    expose:
      - "8545"
      - "8546"
    user: root
    working_dir: /home/parity

  ganache:
    image: trufflesuite/ganache-cli:v6.9.1
    container_name: ganache
    ports:
      - "8555:8555"
    expose:
      - "8555"
    command: "--gasLimit 10000000
    -p 8555
    --account=\"0x91cf2cc3671a365fcbf38010ff97ee31a5b7e674842663c56769e41600696ead,1000000000000000000000000\"
    --account=\"0xc0a550404067ce46a51283e0cc99ec3ba832940064587147a8db9a7ba355ef27,1000000000000000000000000\",
    --account=\"0x6ca1cfaba9715aa485504cb8a3d3fe54191e0991b5f47eb982e8fb40d1b8e8d8,1000000000000000000000000\",
    --account=\"0x1a9e422172e3d84487f7c833e3895f2f65c35eff7e68783adaa0c5bbe741ca8a,1000000000000000000000000\""



================================================
FILE: docs/conf.py
================================================
# -*- coding: utf-8 -*-
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.

import os
import sys
sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('..'))


# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = 'pymaker'
copyright = '2017, MakerDAO'
author = 'MakerDAO'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = ''
# The full version, including alpha/beta/rc tags.
release = ''

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False


# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
html_theme = 'classic'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']


# -- Options for HTMLHelp output ------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'pymaker'


# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    # 'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #
    # 'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #
    # 'preamble': '',

    # Latex figure (float) alignment
    #
    # 'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
    (master_doc, 'pymaker.py.tex', 'pymaker Documentation',
     'MakerDAO', 'manual'),
]


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, 'pymaker', 'pymaker Documentation',
     [author], 1)
]


# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (master_doc, 'pymaker', 'pymaker Documentation',
     author, 'pymaker', 'One line description of project.',
     'Miscellaneous'),
]





================================================
FILE: docs/index.rst
================================================
pymaker API
===========

The `pymaker` API exists to provide a simple way of interacting with Maker smart contracts.

It was designed to simplify and facilitate creation of external profit-seeking agents, usually called keepers,
that operate around the stablecoin set of smart contracts. The API can also be used to automate certain tasks for
other entities involved in the platform, like DAI issuers or traders.


General
-------

Address
~~~~~~~

.. autoclass:: pymaker.Address
    :members:

Transact
~~~~~~~~

.. autoclass:: pymaker.Transact
    :members:

Calldata
~~~~~~~~

.. autoclass:: pymaker.Calldata
    :members:

Invocation
~~~~~~~~~~

.. autoclass:: pymaker.Invocation
    :members:

Receipt
~~~~~~~

.. autoclass:: pymaker.Receipt
    :members:

Transfer
~~~~~~~~

.. autoclass:: pymaker.Transfer
    :members:


Numeric types
-------------

Most of the numeric data throughout the entire platform is kept as either `Wad` (18-digit precision type)
or `Ray` (27-digit precision type).

Wad
~~~

.. autoclass:: pymaker.numeric.Wad
    :members:

Ray
~~~

.. autoclass:: pymaker.numeric.Ray
    :members:


Gas price
---------

.. autoclass:: pymaker.gas.GasPrice
    :members:

The following implementations of `GasPrice` are available:

DefaultGasPrice
~~~~~~~~~~~~~~~

.. autoclass:: pymaker.gas.DefaultGasPrice
    :members:

FixedGasPrice
~~~~~~~~~~~~~

.. autoclass:: pymaker.gas.FixedGasPrice
    :members:

IncreasingGasPrice
~~~~~~~~~~~~~~~~~~

.. autoclass:: pymaker.gas.IncreasingGasPrice
    :members:


Approvals
---------

.. automodule:: pymaker.approval
    :members:


Contracts
---------

DAI Stablecoin
~~~~~~~~~~~~~~

Tub
"""

.. autoclass:: pymaker.sai.Tub
    :members:

Tap
"""

.. autoclass:: pymaker.sai.Tap
    :members:

Top
"""

.. autoclass:: pymaker.sai.Top
    :members:

Vox
"""

.. autoclass:: pymaker.sai.Vox
    :members:

ERC20
~~~~~

ERC20Token
""""""""""

.. autoclass:: pymaker.token.ERC20Token
    :members:

DSToken
"""""""

.. autoclass:: pymaker.token.DSToken
    :members:

DSEthToken
""""""""""

.. autoclass:: pymaker.token.DSEthToken
    :members:


Exchanges
~~~~~~~~~

`OaaisDEX`, `EtherDelta` and `0x` are decentralized exchanges which also provide some arbitrage opportunities
for profit-seeking agents. Because of that an API has been created around them as well. Also an API for
the `Bibox` centralized exchange is present.

OasisDEX
""""""""

.. automodule:: pymaker.oasis
    :members:

EtherDelta
""""""""""

.. automodule:: pymaker.etherdelta
    :members:

0x
""

.. automodule:: pymaker.zrx
    :members:

Bibox
"""""

.. automodule:: pymaker.bibox
    :members:


Authentication
~~~~~~~~~~~~~~

DSGuard
"""""""

.. autoclass:: pymaker.auth.DSGuard
    :members:


DSValue
~~~~~~~

.. autoclass:: pymaker.feed.DSValue
    :members:

DSVault
~~~~~~~

.. autoclass:: pymaker.vault.DSVault
    :members:



Atomic transactions
-------------------

TxManager
~~~~~~~~~

.. autoclass:: pymaker.transactional.TxManager
    :members:


================================================
FILE: pymaker/__init__.py
================================================
# This file is part of Maker Keeper Framework.
#
# Copyright (C) 2017-2018 reverendus
#
# 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 <http://www.gnu.org/licenses/>.

import asyncio
import json
import logging
import re
import requests
import sys
import time
from enum import Enum, auto
from functools import total_ordering, wraps
from threading import Lock
from typing import Optional
from weakref import WeakKeyDictionary

import eth_utils
import pkg_resources
from hexbytes import HexBytes

from web3 import HTTPProvider, Web3
from web3._utils.contracts import get_function_info, encode_abi
from web3._utils.events import get_event_data
from web3.exceptions import TransactionNotFound
from web3.middleware import geth_poa_middleware
from web3.exceptions import LogTopicError, TransactionNotFound

from eth_abi.codec import ABICodec
from eth_abi.registry import registry as default_registry

from pymaker.gas import DefaultGasPrice, GasPrice
from pymaker.numeric import Wad
from pymaker.util import synchronize, bytes_to_hexstring, is_contract_at

filter_threads = []
nonce_calc = WeakKeyDictionary()
next_nonce = {}
transaction_lock = Lock()
logger = logging.getLogger()


def web3_via_http(endpoint_uri: str, timeout=60, http_pool_size=20):
    assert isinstance(endpoint_uri, str)
    adapter = requests.adapters.HTTPAdapter(pool_connections=http_pool_size, pool_maxsize=http_pool_size)
    session = requests.Session()
    if endpoint_uri.startswith("http"):
        # Mount over both existing adaptors created by default (rather than just the one which applies to our URI)
        session.mount('http://', adapter)
        session.mount('https://', adapter)
    else:
        raise ValueError("Unsupported protocol")

    web3 = Web3(HTTPProvider(endpoint_uri=endpoint_uri, request_kwargs={"timeout": timeout}, session=session))
    if web3.net.version == "5":  # goerli
        web3.middleware_onion.inject(geth_poa_middleware, layer=0)
    return web3


class NonceCalculation(Enum):
    TX_COUNT = auto()
    PARITY_NEXTNONCE = auto()
    SERIAL = auto()
    PARITY_SERIAL = auto()


def _get_nonce_calc(web3: Web3) -> NonceCalculation:
    assert isinstance(web3, Web3)
    global nonce_calc
    if web3 not in nonce_calc:
        providers_without_nonce_calculation = ['infura', 'quiknode']
        requires_serial_nonce = any(provider in web3.manager.provider.endpoint_uri for provider in
                                    providers_without_nonce_calculation)
        is_parity = "parity" in web3.clientVersion.lower() or "openethereum" in web3.clientVersion.lower()
        if is_parity and requires_serial_nonce:
            nonce_calc[web3] = NonceCalculation.PARITY_SERIAL
        elif requires_serial_nonce:
            nonce_calc[web3] = NonceCalculation.SERIAL
        elif is_parity:
            nonce_calc[web3] = NonceCalculation.PARITY_NEXTNONCE
        else:
            nonce_calc[web3] = NonceCalculation.TX_COUNT
        logger.debug(f"node clientVersion={web3.clientVersion}, will use {nonce_calc[web3]}")
    return nonce_calc[web3]


def register_filter_thread(filter_thread):
    filter_threads.append(filter_thread)


def any_filter_thread_present() -> bool:
    return len(filter_threads) > 0


def all_filter_threads_alive() -> bool:
    return all(filter_thread_alive(filter_thread) for filter_thread in filter_threads)


def filter_thread_alive(filter_thread) -> bool:
    # it's a wicked way of detecting whether a web3.py filter is still working
    # but unfortunately I wasn't able to find any other one
    return hasattr(filter_thread, '_args') and hasattr(filter_thread, '_kwargs') or not filter_thread.is_alive()


def stop_all_filter_threads():
    for filter_thread in filter_threads:
        try:
            filter_thread.stop_watching(timeout=60)
        except:
            pass


def _track_status(f):
    @wraps(f)
    async def wrapper(*args, **kwds):
        # Check for multiple execution
        if args[0].status != TransactStatus.NEW:
            raise Exception("Each `Transact` can only be executed once")

        # Set current status to in progress
        args[0].status = TransactStatus.IN_PROGRESS

        try:
            return await f(*args, **kwds)
        finally:
            args[0].status = TransactStatus.FINISHED

    return wrapper


@total_ordering
class Address:
    """Represents an Ethereum address.

    Addresses get normalized automatically, so instances of this class can be safely compared to each other.

    Args:
        address: Can be any address representation allowed by web3.py
            or another instance of the Address class.

    Attributes:
        address: Normalized hexadecimal representation of the Ethereum address.
    """
    def __init__(self, address):
        if isinstance(address, Address):
            self.address = address.address
        else:
            self.address = eth_utils.to_checksum_address(address)

    @staticmethod
    def zero():
        return Address("0x0000000000000000000000000000000000000000")

    def as_bytes(self) -> bytes:
        """Return the address as a 20-byte bytes array."""
        return bytes.fromhex(self.address.replace('0x', ''))

    def __str__(self):
        return f"{self.address}"

    def __repr__(self):
        return f"Address('{self.address}')"

    def __hash__(self):
        return self.address.__hash__()

    def __eq__(self, other):
        assert(isinstance(other, Address))
        return self.address == other.address

    def __lt__(self, other):
        assert(isinstance(other, Address))
        return self.address < other.address


class Contract:
    logger = logging.getLogger()

    @staticmethod
    def _deploy(web3: Web3, abi: list, bytecode: str, args: list) -> Address:
        assert(isinstance(web3, Web3))
        assert(isinstance(abi, list))
        assert(isinstance(bytecode, str))
        assert(isinstance(args, list))

        contract = web3.eth.contract(abi=abi, bytecode=bytecode)
        tx_hash = contract.constructor(*args).transact(
            transaction={'from': eth_utils.to_checksum_address(web3.eth.defaultAccount)})
        receipt = web3.eth.getTransactionReceipt(tx_hash)
        return Address(receipt['contractAddress'])

    @staticmethod
    def _get_contract(web3: Web3, abi: list, address: Address):
        assert(isinstance(web3, Web3))
        assert(isinstance(abi, list))
        assert(isinstance(address, Address))

        if not is_contract_at(web3, address):
            raise Exception(f"No contract found at {address}")

        return web3.eth.contract(abi=abi)(address=address.address)

    def _past_events(self, contract, event, cls, number_of_past_blocks, event_filter) -> list:
        block_number = contract.web3.eth.blockNumber
        return self._past_events_in_block_range(contract, event, cls, max(block_number-number_of_past_blocks, 0),
                                                block_number, event_filter)

    def _past_events_in_block_range(self, contract, event, cls, from_block, to_block, event_filter) -> list:
        assert(isinstance(from_block, int))
        assert(isinstance(to_block, int))
        assert(isinstance(event_filter, dict) or (event_filter is None))

        def _event_callback(cls, past):
            def callback(log):
                if past:
                    self.logger.debug(f"Past event {log['event']} discovered, block_number={log['blockNumber']},"
                                      f" tx_hash={bytes_to_hexstring(log['transactionHash'])}")
                else:
                    self.logger.debug(f"Event {log['event']} discovered, block_number={log['blockNumber']},"
                                      f" tx_hash={bytes_to_hexstring(log['transactionHash'])}")
                return cls(log)

            return callback

        result = contract.events[event].createFilter(fromBlock=from_block, toBlock=to_block,
                                                     argument_filters=event_filter).get_all_entries()

        return list(map(_event_callback(cls, True), result))

    @staticmethod
    def _load_abi(package, resource) -> list:
        return json.loads(pkg_resources.resource_string(package, resource))

    @staticmethod
    def _load_bin(package, resource) -> str:
        return str(pkg_resources.resource_string(package, resource), "utf-8")


class Calldata:
    """Represents Ethereum calldata.

    Attributes:
        value: Calldata as either a string starting with `0x`, or as bytes.
    """
    def __init__(self, value):
        if isinstance(value, str):
            assert(value.startswith('0x'))
            self.value = value

        elif isinstance(value, bytes):
            self.value = bytes_to_hexstring(value)

        else:
            raise Exception(f"Unable to create calldata from '{value}'")

    @classmethod
    def from_signature(cls, web3: Web3, fn_sign: str, fn_args: list):
        """ Allow to create a `Calldata` from a function signature and a list of arguments.

        :param fn_sign: the function signature ie. "function(uint256,address)"
        :param fn_args: arguments to the function ie. [123, "0x00...00"]
        """
        assert isinstance(fn_sign, str)
        assert isinstance(fn_args, list)

        fn_split = re.split('[(),]', fn_sign)
        fn_name = fn_split[0]
        fn_args_type = [{"type": type} for type in fn_split[1:] if type]

        fn_abi = {"type": "function", "name": fn_name, "inputs": fn_args_type}
        fn_abi, fn_selector, fn_arguments = get_function_info("test", abi_codec=web3.codec, fn_abi=fn_abi, args=fn_args)

        calldata = encode_abi(web3, fn_abi, fn_arguments, fn_selector)

        return cls(calldata)

    @classmethod
    def from_contract_abi(cls, web3: Web3, fn_sign: str, fn_args: list, contract_abi):
        """ Create a `Calldata` according to the given contract abi """
        assert isinstance(web3, Web3)
        assert isinstance(fn_sign, str)
        assert isinstance(fn_args, list)

        fn_split = re.split('[(),]', fn_sign)
        fn_name = fn_split[0]

        fn_abi, fn_selector, fn_arguments = get_function_info(fn_name, abi_codec=web3.codec, contract_abi=contract_abi, args=fn_args)
        calldata = encode_abi(web3, fn_abi, fn_arguments, fn_selector)

        return cls(calldata)

    def as_bytes(self) -> bytes:
        """Return the calldata as a byte array."""
        return bytes.fromhex(self.value.replace('0x', ''))

    def __str__(self):
        return f"{self.value}"

    def __repr__(self):
        return f"Calldata('{self.value}')"

    def __hash__(self):
        return self.value.__hash__()

    def __eq__(self, other):
        assert(isinstance(other, Calldata))
        return self.value == other.value


class Invocation(object):
    """Single contract method invocation, to be used together with `TxManager`.

    Attributes:
        address: Contract address.
        calldata: The calldata of the invocation.
    """
    def __init__(self, address: Address, calldata: Calldata):
        assert(isinstance(address, Address))
        assert(isinstance(calldata, Calldata))
        self.address = address
        self.calldata = calldata


class Receipt:
    """Represents a receipt for an Ethereum transaction.

    Attributes:
        raw_receipt: Raw receipt received from the Ethereum node.
        transaction_hash: Hash of the Ethereum transaction.
        gas_used: Amount of gas used by the Ethereum transaction.
        transfers: A list of ERC20 token transfers resulting from the execution
            of this Ethereum transaction. Each transfer is an instance of the
            :py:class:`pymaker.Transfer` class.
        result: Transaction-specific return value (i.e. new order id for Oasis
            order creation transaction).
        successful: Boolean flag which is `True` if the Ethereum transaction
            was successful. We consider transaction successful if the contract
            method has been executed without throwing.
    """
    def __init__(self, receipt):
        self.raw_receipt = receipt
        self.transaction_hash = receipt['transactionHash']
        self.gas_used = receipt['gasUsed']
        self.transfers = []
        self.result = None

        receipt_logs = receipt['logs']
        if (receipt_logs is not None) and (len(receipt_logs) > 0):
            self.successful = True
            for receipt_log in receipt_logs:
                if len(receipt_log['topics']) > 0:
                    # $ seth keccak $(seth --from-ascii "Transfer(address,address,uint256)")
                    # 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
                    if receipt_log['topics'][0] == HexBytes('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'):
                        from pymaker.token import ERC20Token
                        transfer_abi = [abi for abi in ERC20Token.abi if abi.get('name') == 'Transfer'][0]
                        codec = ABICodec(default_registry)
                        try:
                            event_data = get_event_data(codec, transfer_abi, receipt_log)
                            self.transfers.append(Transfer(token_address=Address(event_data['address']),
                                                           from_address=Address(event_data['args']['from']),
                                                           to_address=Address(event_data['args']['to']),
                                                           value=Wad(event_data['args']['value'])))
                        # UniV3 Mint logIndex: 3 has an NFT mint of 1, from null, to a given address, but only 2 types (address, address)
                        except LogTopicError:
                            continue

                    # $ seth keccak $(seth --from-ascii "Mint(address,uint256)")
                    # 0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885
                    if receipt_log['topics'][0] == HexBytes('0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885'):
                        from pymaker.token import DSToken
                        transfer_abi = [abi for abi in DSToken.abi if abi.get('name') == 'Mint'][0]
                        codec = ABICodec(default_registry)
                        event_data = get_event_data(codec, transfer_abi, receipt_log)
                        self.transfers.append(Transfer(token_address=Address(event_data['address']),
                                                       from_address=Address('0x0000000000000000000000000000000000000000'),
                                                       to_address=Address(event_data['args']['guy']),
                                                       value=Wad(event_data['args']['wad'])))

                    # $ seth keccak $(seth --from-ascii "Burn(address,uint256)")
                    # 0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5
                    if receipt_log['topics'][0] == HexBytes('0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5'):
                        from pymaker.token import DSToken
                        transfer_abi = [abi for abi in DSToken.abi if abi.get('name') == 'Burn'][0]
                        codec = ABICodec(default_registry)
                        event_data = get_event_data(codec, transfer_abi, receipt_log)
                        self.transfers.append(Transfer(token_address=Address(event_data['address']),
                                                       from_address=Address(event_data['args']['guy']),
                                                       to_address=Address('0x0000000000000000000000000000000000000000'),
                                                       value=Wad(event_data['args']['wad'])))

        else:
            self.successful = False

    @property
    def logs(self):
        return self.raw_receipt['logs']


class TransactStatus(Enum):
     NEW = auto()
     IN_PROGRESS = auto()
     FINISHED = auto()


def get_pending_transactions(web3: Web3, address: Address = None) -> list:
    """Retrieves a list of pending transactions from the mempool."""
    assert isinstance(web3, Web3)
    assert isinstance(address, Address) or address is None

    if address is None:
        address = Address(web3.eth.defaultAccount)

    # Get the list of pending transactions and their details from specified sources
    if _get_nonce_calc(web3) in (NonceCalculation.PARITY_NEXTNONCE, NonceCalculation.PARITY_SERIAL):
        items = web3.manager.request_blocking("parity_pendingTransactions", [])
        items = filter(lambda item: item['from'].lower() == address.address.lower(), items)
        items = filter(lambda item: item['blockNumber'] is None, items)
        txes = map(lambda item: RecoveredTransact(web3=web3, address=address, nonce=int(item['nonce'], 16),
                                                  latest_tx_hash=item['hash'], current_gas=int(item['gasPrice'], 16)),
                   items)
    else:
        items = web3.manager.request_blocking("eth_getBlockByNumber", ["pending", True])['transactions']
        items = filter(lambda item: item['from'].lower() == address.address.lower(), items)
        list(items)  # Unsure why this is required
        txes = map(lambda item: RecoveredTransact(web3=web3, address=address, nonce=item['nonce'],
                                                  latest_tx_hash=item['hash'], current_gas=item['gasPrice']),
                   items)

    return list(txes)


class Transact:
    """Represents an Ethereum transaction before it gets executed."""

    logger = logging.getLogger()
    gas_estimate_for_bad_txs = None

    def __init__(self,
                 origin: Optional[object],
                 web3: Web3,
                 abi: Optional[list],
                 address: Address,
                 contract: Optional[object],
                 function_name: Optional[str],
                 parameters: Optional[list],
                 extra: Optional[dict] = None,
                 result_function=None):
        assert(isinstance(origin, object) or (origin is None))
        assert(isinstance(web3, Web3))
        assert(isinstance(abi, list) or (abi is None))
        assert(isinstance(address, Address))
        assert(isinstance(contract, object) or (contract is None))
        assert(isinstance(function_name, str) or (function_name is None))
        assert(isinstance(parameters, list) or (parameters is None))
        assert(isinstance(extra, dict) or (extra is None))
        assert(callable(result_function) or (result_function is None))

        self.origin = origin
        self.web3 = web3
        self.abi = abi
        self.address = address
        self.contract = contract
        self.function_name = function_name
        self.parameters = parameters
        self.extra = extra
        self.result_function = result_function
        self.initial_time = None
        self.status = TransactStatus.NEW
        self.nonce = None
        self.replaced = False
        self.gas_price = None
        self.gas_price_last = 0
        self.tx_hashes = []

    def _get_receipt(self, transaction_hash: str) -> Optional[Receipt]:
        try:
            raw_receipt = self.web3.eth.getTransactionReceipt(transaction_hash)
            if raw_receipt is not None and raw_receipt['blockNumber'] is not None:
                receipt = Receipt(raw_receipt)
                receipt.result = self.result_function(receipt) if self.result_function is not None else None
                return receipt
        except (TransactionNotFound, ValueError):
            self.logger.debug(f"Transaction {transaction_hash} not found (may have been dropped/replaced)")
        return None

    def _as_dict(self, dict_or_none) -> dict:
        if dict_or_none is None:
            return {}
        else:
            return dict(**dict_or_none)

    def _gas(self, gas_estimate: int, **kwargs) -> int:
        if 'gas' in kwargs and 'gas_buffer' in kwargs:
            raise Exception('"gas" and "gas_buffer" keyword arguments may not be specified at the same time')

        if 'gas' in kwargs:
            return kwargs['gas']
        elif 'gas_buffer' in kwargs:
            return gas_estimate + kwargs['gas_buffer']
        else:
            return gas_estimate + 100000

    def _func(self, from_account: str, gas: int, gas_price: Optional[int], nonce: Optional[int]):
        gas_price_dict = {'gasPrice': gas_price} if gas_price is not None else {}
        nonce_dict = {'nonce': nonce} if nonce is not None else {}

        transaction_params = {**{'from': from_account, 'gas': gas},
                              **gas_price_dict,
                              **nonce_dict,
                              **self._as_dict(self.extra)}

        if self.contract is not None:
            if self.function_name is None:

                return bytes_to_hexstring(self.web3.eth.sendTransaction({**transaction_params,
                                                                         **{'to': self.address.address,
                                                                            'data': self.parameters[0]}}))
            else:
                return bytes_to_hexstring(self._contract_function().transact(transaction_params))
        else:
            return bytes_to_hexstring(self.web3.eth.sendTransaction({**transaction_params,
                                                                     **{'to': self.address.address}}))

    def _contract_function(self):
        if '(' in self.function_name:
            function_factory = self.contract.get_function_by_signature(self.function_name)

        else:
            function_factory = self.contract.get_function_by_name(self.function_name)

        return function_factory(*self.parameters)

    def name(self) -> str:
        """Returns the nicely formatted name of this pending Ethereum transaction.

        Returns:
            Nicely formatted name of this pending Ethereum transaction.
        """
        if self.origin:
            def format_parameter(parameter):
                if isinstance(parameter, bytes):
                    return bytes_to_hexstring(parameter)
                else:
                    return parameter

            formatted_parameters = str(list(map(format_parameter, self.parameters))).lstrip("[").rstrip("]")
            name = f"{repr(self.origin)}.{self.function_name}({formatted_parameters})"
        else:
            name = f"Regular transfer to {self.address}"

        return name if self.extra is None else name + f" with {self.extra}"

    def estimated_gas(self, from_address: Address) -> int:
        """Return an estimated amount of gas which will get consumed by this Ethereum transaction.

        May throw an exception if the actual transaction will fail as well.

        Args:
            from_address: Address to simulate sending the transaction from.

        Returns:
            Amount of gas as an integer.
        """
        assert(isinstance(from_address, Address))

        if self.contract is not None:
            if self.function_name is None:
                return self.web3.eth.estimateGas({**self._as_dict(self.extra), **{'from': from_address.address,
                                                                                  'to': self.address.address,
                                                                                  'data': self.parameters[0]}})

            else:
                estimate = self._contract_function() \
                        .estimateGas({**self._as_dict(self.extra), **{'from': from_address.address}})

        else:
            estimate = 21000

        return estimate

    def transact(self, **kwargs) -> Optional[Receipt]:
        """Executes the Ethereum transaction synchronously.

        Executes the Ethereum transaction synchronously. The method will block until the
        transaction gets mined i.e. it will return when either the transaction execution
        succeeded or failed. In case of the former, a :py:class:`pymaker.Receipt`
        object will be returned.

        Out-of-gas exceptions are automatically recognized as transaction failures.

        Allowed keyword arguments are: `from_address`, `replace`, `gas`, `gas_buffer`, `gas_price`.
        `gas_price` needs to be an instance of a class inheriting from :py:class:`pymaker.gas.GasPrice`.
        `from_address` needs to be an instance of :py:class:`pymaker.Address`.

        The `gas` keyword argument is the gas limit for the transaction, whereas `gas_buffer`
        specifies how much gas should be added to the estimate. They can not be present
        at the same time. If none of them are present, a default buffer is added to the estimate.

        Returns:
            A :py:class:`pymaker.Receipt` object if the transaction invocation was successful.
            `None` otherwise.
        """
        return synchronize([self.transact_async(**kwargs)])[0]

    @_track_status
    async def transact_async(self, **kwargs) -> Optional[Receipt]:
        """Executes the Ethereum transaction asynchronously.

        Executes the Ethereum transaction asynchronously. The method will return immediately.
        Ultimately, its future value will become either a :py:class:`pymaker.Receipt` or `None`,
        depending on whether the transaction execution was successful or not.

        Out-of-gas exceptions are automatically recognized as transaction failures.

        Allowed keyword arguments are: `from_address`, `replace`, `gas`, `gas_buffer`, `gas_price`.
        `gas_price` needs to be an instance of a class inheriting from :py:class:`pymaker.gas.GasPrice`.

        The `gas` keyword argument is the gas limit for the transaction, whereas `gas_buffer`
        specifies how much gas should be added to the estimate. They can not be present
        at the same time. If none of them are present, a default buffer is added to the estimate.

        Returns:
            A future value of either a :py:class:`pymaker.Receipt` object if the transaction
            invocation was successful, or `None` if it failed.
        """

        global next_nonce
        self.initial_time = time.time()
        unknown_kwargs = set(kwargs.keys()) - {'from_address', 'replace', 'gas', 'gas_buffer', 'gas_price'}
        if len(unknown_kwargs) > 0:
            raise ValueError(f"Unknown kwargs: {unknown_kwargs}")

        # Get the from account; initialize the first nonce for the account.
        from_account = kwargs['from_address'].address if ('from_address' in kwargs) else self.web3.eth.defaultAccount
        if not next_nonce or from_account not in next_nonce:
            next_nonce[from_account] = self.web3.eth.getTransactionCount(from_account, block_identifier='pending')

        # First we try to estimate the gas usage of the transaction. If gas estimation fails
        # it means there is no point in sending the transaction, thus we fail instantly and
        # do not increment the nonce. If the estimation is successful, we pass the calculated
        # gas value (plus some `gas_buffer`) to the subsequent `transact` calls so it does not
        # try to estimate it again.
        try:
            gas_estimate = self.estimated_gas(Address(from_account))
        except:
            if Transact.gas_estimate_for_bad_txs:
                self.logger.warning(f"Transaction {self.name()} will fail, submitting anyway")
                gas_estimate = Transact.gas_estimate_for_bad_txs
            else:
                self.logger.warning(f"Transaction {self.name()} will fail, refusing to send ({sys.exc_info()[1]})")
                return None

        # Get or calculate `gas`. Get `gas_price`, which in fact refers to a gas pricing algorithm.
        gas = self._gas(gas_estimate, **kwargs)
        self.gas_price = kwargs['gas_price'] if ('gas_price' in kwargs) else DefaultGasPrice()
        assert(isinstance(self.gas_price, GasPrice))

        # Get the transaction this one is supposed to replace.
        # If there is one, try to borrow the nonce from it as long as that transaction isn't finished.
        replaced_tx = kwargs['replace'] if ('replace' in kwargs) else None
        if replaced_tx is not None:
            while replaced_tx.nonce is None and replaced_tx.status != TransactStatus.FINISHED:
                await asyncio.sleep(0.25)

            replaced_tx.replaced = True
            self.nonce = replaced_tx.nonce
            # Gas should be calculated from the original time of submission
            self.initial_time = replaced_tx.initial_time if replaced_tx.initial_time else time.time()
            # Use gas strategy from the original transaction if one was not provided
            if 'gas_price' not in kwargs:
                self.gas_price = replaced_tx.gas_price if replaced_tx.gas_price else DefaultGasPrice()
            self.gas_price_last = replaced_tx.gas_price_last
            # Detain replacement until gas strategy produces a price acceptable to the node
            if replaced_tx.tx_hashes:
                most_recent_tx = replaced_tx.tx_hashes[-1]
                self.tx_hashes = [most_recent_tx]

        while True:
            seconds_elapsed = int(time.time() - self.initial_time)

            # CAUTION: if transact_async is called rapidly, we will hammer the node with these JSON-RPC requests
            if self.nonce is not None and self.web3.eth.getTransactionCount(from_account) > self.nonce:
                # Check if any transaction sent so far has been mined (has a receipt).
                # If it has, we return either the receipt (if if was successful) or `None`.
                for attempt in range(1, 11):
                    if self.replaced:
                        self.logger.info(f"Transaction with nonce={self.nonce} was replaced with a newer transaction")
                        return None

                    for tx_hash in self.tx_hashes:
                        receipt = self._get_receipt(tx_hash)
                        if receipt:
                            if receipt.successful:
                                self.logger.info(f"Transaction {self.name()} was successful (tx_hash={tx_hash})")
                                return receipt
                            else:
                                self.logger.warning(f"Transaction {self.name()} mined successfully but generated no single"
                                                    f" log entry, assuming it has failed (tx_hash={tx_hash})")
                                return None

                    self.logger.debug(f"No receipt found in attempt #{attempt}/10 (nonce={self.nonce},"
                                      f" getTransactionCount={self.web3.eth.getTransactionCount(from_account)})")

                    await asyncio.sleep(0.5)

                # If we can not find a mined receipt but at the same time we know last used nonce
                # has increased, then it means that the transaction we tried to send failed.
                self.logger.warning(f"Transaction {self.name()} has been overridden by another transaction"
                                    f" with the same nonce, which means it has failed")
                return None

            # Trap replacement after the tx has entered the mempool and before it has been mined
            if self.replaced:
                self.logger.info(f"Transaction {self.name()} with nonce={self.nonce} is being replaced")
                return None

            # Send a transaction if:
            # - no transaction has been sent yet, or
            # - the requested gas price has changed enough since the last transaction has been sent
            # - the gas price on a replacement has sufficiently exceeded that of the original transaction
            gas_price_value = self.gas_price.get_gas_price(seconds_elapsed)
            transaction_was_sent = len(self.tx_hashes) > 0 or (replaced_tx is not None and len(replaced_tx.tx_hashes) > 0)
            # Uncomment this to debug state during transaction submission
            # self.logger.debug(f"Transaction {self.name()} is churning: was_sent={transaction_was_sent}, gas_price_value={gas_price_value} gas_price_last={self.gas_price_last}")
            if not transaction_was_sent or (gas_price_value is not None and gas_price_value > self.gas_price_last * 1.125):
                self.gas_price_last = gas_price_value

                try:
                    # We need the lock in order to not try to send two transactions with the same nonce.
                    with transaction_lock:
                        if self.nonce is None:
                            nonce_calculation = _get_nonce_calc(self.web3)
                            if nonce_calculation == NonceCalculation.PARITY_NEXTNONCE:
                                self.nonce = int(self.web3.manager.request_blocking("parity_nextNonce", [from_account]), 16)
                            elif nonce_calculation == NonceCalculation.TX_COUNT:
                                self.nonce = self.web3.eth.getTransactionCount(from_account, block_identifier='pending')
                            elif nonce_calculation == NonceCalculation.SERIAL:
                                tx_count = self.web3.eth.getTransactionCount(from_account, block_identifier='pending')
                                next_serial = next_nonce[from_account]
                                self.nonce = max(tx_count, next_serial)
                            elif nonce_calculation == NonceCalculation.PARITY_SERIAL:
                                tx_count = int(self.web3.manager.request_blocking("parity_nextNonce", [from_account]), 16)
                                next_serial = next_nonce[from_account]
                                self.nonce = max(tx_count, next_serial)
                            next_nonce[from_account] = self.nonce + 1

                        # Trap replacement while original is holding the lock awaiting nonce assignment
                        if self.replaced:
                            self.logger.info(f"Transaction {self.name()} with nonce={self.nonce} was replaced")
                            return None

                        tx_hash = self._func(from_account, gas, gas_price_value, self.nonce)
                        self.tx_hashes.append(tx_hash)

                    self.logger.info(f"Sent transaction {self.name()} with nonce={self.nonce}, gas={gas},"
                                     f" gas_price={gas_price_value if gas_price_value is not None else 'default'}"
                                     f" (tx_hash={tx_hash})")
                except Exception as e:
                    self.logger.warning(f"Failed to send transaction {self.name()} with nonce={self.nonce}, gas={gas},"
                                        f" gas_price={gas_price_value if gas_price_value is not None else 'default'}"
                                        f" ({e})")

                    if len(self.tx_hashes) == 0:
                        raise

            await asyncio.sleep(0.25)

    def invocation(self) -> Invocation:
        """Returns the `Invocation` object for this pending Ethereum transaction.

        The :py:class:`pymaker.Invocation` object may be used with :py:class:`pymaker.transactional.TxManager`
        to invoke multiple contract calls in one Ethereum transaction.

        Please see :py:class:`pymaker.transactional.TxManager` documentation for more details.

        Returns:
            :py:class:`pymaker.Invocation` object for this pending Ethereum transaction.
        """
        return Invocation(self.address, Calldata(self._contract_function()._encode_transaction_data()))


class RecoveredTransact(Transact):
    """ Models a pending transaction retrieved from the mempool.

    These can be created by a call to `get_pending_transactions`, enabling the consumer to implement logic which
    cancels pending transactions upon keeper/bot startup.
    """
    def __init__(self, web3: Web3,
                 address: Address,
                 nonce: int,
                 latest_tx_hash: str,
                 current_gas: int):
        assert isinstance(current_gas, int)
        super().__init__(origin=None,
                         web3=web3,
                         abi=None,
                         address=address,
                         contract=None,
                         function_name=None,
                         parameters=None)
        self.nonce = nonce
        self.tx_hashes.append(latest_tx_hash)
        self.current_gas = current_gas

    def name(self):
        return f"Recovered tx with nonce {self.nonce}"

    @_track_status
    async def transact_async(self, **kwargs) -> Optional[Receipt]:
        # TODO: Read transaction data from chain, create a new state machine to manage gas for the transaction.
        raise NotImplementedError()

    def cancel(self, gas_price: GasPrice):
        return synchronize([self.cancel_async(gas_price)])[0]

    async def cancel_async(self, gas_price: GasPrice):
        assert isinstance(gas_price, GasPrice)
        initial_time = time.time()
        self.gas_price_last = self.current_gas
        self.tx_hashes.clear()

        if gas_price.get_gas_price(0) <= self.current_gas * 1.125:
            self.logger.warning(f"Recovery gas price is less than current gas price {self.current_gas}; "
                                "cancellation will be deferred until the strategy produces an acceptable price.")

        while True:
            seconds_elapsed = int(time.time() - initial_time)
            gas_price_value = gas_price.get_gas_price(seconds_elapsed)
            if gas_price_value > self.gas_price_last * 1.125:
                self.gas_price_last = gas_price_value
                # Transaction lock isn't needed here, as we are replacing an existing nonce
                tx_hash = bytes_to_hexstring(self.web3.eth.sendTransaction({'from': self.address.address,
                                                                            'to': self.address.address,
                                                                            'gasPrice': gas_price_value,
                                                                            'nonce': self.nonce,
                                                                            'value': 0}))
                self.tx_hashes.append(tx_hash)
                self.logger.info(f"Attempting to cancel recovered tx with nonce={self.nonce}, "
                                 f"gas_price={gas_price_value} (tx_hash={tx_hash})")

            for tx_hash in self.tx_hashes:
                receipt = self._get_receipt(tx_hash)
                if receipt:
                    self.logger.info(f"{self.name()} was cancelled (tx_hash={tx_hash})")
                    return

            await asyncio.sleep(0.75)


class Transfer:
    """Represents an ERC20 token transfer.

    Represents an ERC20 token transfer resulting from contract method execution.
    A list of transfers can be found in the :py:class:`pymaker.Receipt` class.

    Attributes:
        token_address: Address of the ERC20 token that has been transferred.
        from_address: Source address of the transfer.
        to_address: Destination address of the transfer.
        value: Value transferred.
    """
    def __init__(self, token_address: Address, from_address: Address, to_address: Address, value: Wad):
        assert(isinstance(token_address, Address))
        assert(isinstance(from_address, Address))
        assert(isinstance(to_address, Address))
        assert(isinstance(value, Wad))
        self.token_address = token_address
        self.from_address = from_address
        self.to_address = to_address
        self.value = value

    def __eq__(self, other):
        assert(isinstance(other, Transfer))
        return self.token_address == other.token_address and \
               self.from_address == other.from_address and \
               self.to_address == other.to_address and \
               self.value == other.value

    def __hash__(self):
        return hash((self.token_address, self.from_address, self.token_address, self.value))


def eth_transfer(web3: Web3, to: Address, amount: Wad) -> Transact:
    return Transact(None, web3, None, to, None, None, None, {'value': amount.value})


================================================
FILE: pymaker/abi/Cat.abi
================================================
[{"inputs":[{"internalType":"address","name":"vat_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"ilk","type":"bytes32"},{"indexed":true,"internalType":"address","name":"urn","type":"address"},{"indexed":false,"internalType":"uint256","name":"ink","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"art","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tab","type":"uint256"},{"indexed":false,"internalType":"address","name":"flip","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Bite","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":true,"internalType":"address","name":"usr","type":"address"},{"indexed":true,"internalType":"bytes32","name":"arg1","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"arg2","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"LogNote","type":"event"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"address","name":"urn","type":"address"}],"name":"bite","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"box","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"cage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"rad","type":"uint256"}],"name":"claw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"uint256","name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"uint256","name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"address","name":"data","type":"address"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"address","name":"flip","type":"address"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"ilks","outputs":[{"internalType":"address","name":"flip","type":"address"},{"internalType":"uint256","name":"chop","type":"uint256"},{"internalType":"uint256","name":"dunk","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"litter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"live","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"vat","outputs":[{"internalType":"contract VatLike","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vow","outputs":[{"internalType":"contract VowLike","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]


================================================
FILE: pymaker/abi/Clipper.abi
================================================
[{"inputs":[{"internalType":"address","name":"vat_","type":"address"},{"internalType":"address","name":"spotter_","type":"address"},{"internalType":"address","name":"dog_","type":"address"},{"internalType":"bytes32","name":"ilk_","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"usr","type":"address"}],"name":"Deny","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"data","type":"uint256"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"address","name":"data","type":"address"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"top","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tab","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lot","type":"uint256"},{"indexed":true,"internalType":"address","name":"usr","type":"address"},{"indexed":true,"internalType":"address","name":"kpr","type":"address"},{"indexed":false,"internalType":"uint256","name":"coin","type":"uint256"}],"name":"Kick","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"top","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tab","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lot","type":"uint256"},{"indexed":true,"internalType":"address","name":"usr","type":"address"},{"indexed":true,"internalType":"address","name":"kpr","type":"address"},{"indexed":false,"internalType":"uint256","name":"coin","type":"uint256"}],"name":"Redo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"usr","type":"address"}],"name":"Rely","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"max","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"owe","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tab","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lot","type":"uint256"},{"indexed":true,"internalType":"address","name":"usr","type":"address"}],"name":"Take","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Yank","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"active","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calc","outputs":[{"internalType":"contract AbacusLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chip","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cusp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"deny","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dog","outputs":[{"internalType":"contract DogLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"uint256","name":"data","type":"uint256"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"address","name":"data","type":"address"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getStatus","outputs":[{"internalType":"bool","name":"needsRedo","type":"bool"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"lot","type":"uint256"},{"internalType":"uint256","name":"tab","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ilk","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tab","type":"uint256"},{"internalType":"uint256","name":"lot","type":"uint256"},{"internalType":"address","name":"usr","type":"address"},{"internalType":"address","name":"kpr","type":"address"}],"name":"kick","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"kicks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"list","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"kpr","type":"address"}],"name":"redo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"rely","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"sales","outputs":[{"internalType":"uint256","name":"pos","type":"uint256"},{"internalType":"uint256","name":"tab","type":"uint256"},{"internalType":"uint256","name":"lot","type":"uint256"},{"internalType":"address","name":"usr","type":"address"},{"internalType":"uint96","name":"tic","type":"uint96"},{"internalType":"uint256","name":"top","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"spotter","outputs":[{"internalType":"contract SpotterLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stopped","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tail","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amt","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"take","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tip","outputs":[{"internalType":"uint192","name":"","type":"uint192"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"upchost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vat","outputs":[{"internalType":"contract VatLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"yank","outputs":[],"stateMutability":"nonpayable","type":"function"}]


================================================
FILE: pymaker/abi/ClipperCallee.abi
================================================
[{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"clipperCall","outputs":[],"stateMutability":"nonpayable","type":"function"}]


================================================
FILE: pymaker/abi/DSAuth.abi
================================================
[{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]

================================================
FILE: pymaker/abi/DSChief.abi
================================================
[{"inputs":[{"internalType":"contract DSToken","name":"GOV","type":"address"},{"internalType":"contract DSToken","name":"IOU","type":"address"},{"internalType":"uint256","name":"MAX_YAYS","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"slate","type":"bytes32"}],"name":"Etch","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":true,"internalType":"address","name":"guy","type":"address"},{"indexed":true,"internalType":"bytes32","name":"foo","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"bar","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"},{"constant":true,"inputs":[],"name":"GOV","outputs":[{"internalType":"contract DSToken","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"IOU","outputs":[{"internalType":"contract DSToken","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_YAYS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"internalType":"contract DSAuthority","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"code","type":"address"},{"internalType":"bytes4","name":"sig","type":"bytes4"}],"name":"canCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"yays","type":"address[]"}],"name":"etch","outputs":[{"internalType":"bytes32","name":"slate","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"free","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"code","type":"address"},{"internalType":"bytes4","name":"sig","type":"bytes4"}],"name":"getCapabilityRoles","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"getUserRoles","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"uint8","name":"role","type":"uint8"}],"name":"hasUserRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"hat","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"code","type":"address"},{"internalType":"bytes4","name":"sig","type":"bytes4"}],"name":"isCapabilityPublic","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"isUserRoot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"last","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"launch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"whom","type":"address"}],"name":"lift","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"live","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"lock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract DSAuthority","name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"code","type":"address"},{"internalType":"bytes4","name":"sig","type":"bytes4"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setPublicCapability","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint8","name":"role","type":"uint8"},{"internalType":"address","name":"code","type":"address"},{"internalType":"bytes4","name":"sig","type":"bytes4"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setRoleCapability","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setRootUser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"uint8","name":"role","type":"uint8"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setUserRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"slates","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"slate","type":"bytes32"}],"name":"vote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"yays","type":"address[]"}],"name":"vote","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"votes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"}]

================================================
FILE: pymaker/abi/DSEthToken.abi
================================================
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"type":"function"},{"constant":false,"inputs":[],"name":"wrap","outputs":[],"payable":true,"type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"guy","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"unwrap","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"tryWithdraw","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]

================================================
FILE: pymaker/abi/DSGuard.abi
================================================
[{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"sig","type":"bytes32"}],"name":"forbid","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"bytes32"},{"name":"dst","type":"bytes32"},{"name":"sig","type":"bytes32"}],"name":"forbid","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"ANY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"src_","type":"address"},{"name":"dst_","type":"address"},{"name":"sig","type":"bytes4"}],"name":"canCall","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"sig","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"bytes32"},{"name":"dst","type":"bytes32"},{"name":"sig","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"bytes32"},{"indexed":true,"name":"dst","type":"bytes32"},{"indexed":true,"name":"sig","type":"bytes32"}],"name":"LogPermit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"bytes32"},{"indexed":true,"name":"dst","type":"bytes32"},{"indexed":true,"name":"sig","type":"bytes32"}],"name":"LogForbid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]

================================================
FILE: pymaker/abi/DSPause.abi
================================================
[{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"usr","type":"address"},{"name":"fax","type":"bytes"},{"name":"era","type":"uint256"}],"name":"drop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"delay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"usr","type":"address"},{"name":"fax","type":"bytes"},{"name":"era","type":"uint256"}],"name":"plan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"plans","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"usr","type":"address"},{"name":"fax","type":"bytes"},{"name":"era","type":"uint256"}],"name":"exec","outputs":[{"name":"response","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"delay_","type":"uint256"},{"name":"owner_","type":"address"},{"name":"authority_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"usr","type":"address"},{"indexed":false,"name":"fax","type":"bytes"},{"indexed":false,"name":"era","type":"uint256"}],"name":"Plan","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"usr","type":"address"},{"indexed":false,"name":"fax","type":"bytes"},{"indexed":false,"name":"era","type":"uint256"}],"name":"Drop","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"usr","type":"address"},{"indexed":false,"name":"fax","type":"bytes"},{"indexed":false,"name":"era","type":"uint256"}],"name":"Exec","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]

================================================
FILE: pymaker/abi/DSProxy.abi
================================================
[{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_target","type":"address"},{"name":"_data","type":"bytes"}],"name":"execute","outputs":[{"name":"response","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"bytes"},{"name":"_data","type":"bytes"}],"name":"execute","outputs":[{"name":"target","type":"address"},{"name":"response","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"cache","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cacheAddr","type":"address"}],"name":"setCache","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_cacheAddr","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]

================================================
FILE: pymaker/abi/DSProxyCache.abi
================================================
[{"constant":false,"inputs":[{"name":"_code","type":"bytes"}],"name":"write","outputs":[{"name":"target","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_code","type":"bytes"}],"name":"read","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]

================================================
FILE: pymaker/abi/DSProxyFactory.abi
================================================
[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isProxy","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cache","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"build","outputs":[{"name":"proxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"owner","type":"address"}],"name":"build","outputs":[{"name":"proxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"owner","type":"address"},{"indexed":false,"name":"proxy","type":"address"},{"indexed":false,"name":"cache","type":"address"}],"name":"Created","type":"event"}]

================================================
FILE: pymaker/abi/DSRoles.abi
================================================
[{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"getUserRoles","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"code","type":"address"},{"name":"sig","type":"bytes4"}],"name":"getCapabilityRoles","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"code","type":"address"},{"name":"sig","type":"bytes4"}],"name":"isCapabilityPublic","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"who","type":"address"},{"name":"role","type":"uint8"},{"name":"enabled","type":"bool"}],"name":"setUserRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"role","type":"uint8"},{"name":"code","type":"address"},{"name":"sig","type":"bytes4"},{"name":"enabled","type":"bool"}],"name":"setRoleCapability","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"},{"name":"role","type":"uint8"}],"name":"hasUserRole","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"caller","type":"address"},{"name":"code","type":"address"},{"name":"sig","type":"bytes4"}],"name":"canCall","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"code","type":"address"},{"name":"sig","type":"bytes4"},{"name":"enabled","type":"bool"}],"name":"setPublicCapability","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"who","type":"address"},{"name":"enabled","type":"bool"}],"name":"setRootUser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"isUserRoot","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]

================================================
FILE: pymaker/abi/DSToken.abi
================================================
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name_","type":"bytes32"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"push","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"move","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"start","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"guy","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"wad","type":"uint256"}],"name":"pull","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"symbol_","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"}]

================================================
FILE: pymaker/abi/DSValue.abi
================================================
[{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wut","type":"bytes32"}],"name":"poke","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"read","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"peek","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"void","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]

================================================
FILE: pymaker/abi/DSVault.abi
================================================
[{"constant":false,"inputs":[{"name":"token_","type":"address"}],"name":"swap","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint128"}],"name":"push","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint128"}],"name":"push","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"}],"name":"pull","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"src","type":"address"}],"name":"pull","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint128"}],"name":"mint","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"src","type":"address"},{"name":"wad","type":"uint128"}],"name":"pull","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"wad","type":"uint128"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"wad","type":"uint128"}],"name":"pull","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"}],"name":"push","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint128"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"dst","type":"address"}],"name":"push","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"wad","type":"uint128"}],"name":"mint","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]

================================================
FILE: pymaker/abi/DaiJoin.abi
================================================
[{"inputs":[{"internalType":"address","name":"vat_","type":"address"},{"internalType":"address","name":"dai_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":true,"internalType":"address","name":"usr","type":"address"},{"indexed":true,"internalType":"bytes32","name":"arg1","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"arg2","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"LogNote","type":"event"},{"constant":false,"inputs":[],"name":"cage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"dai","outputs":[{"internalType":"contract DSTokenLike","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"usr","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"exit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"usr","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"join","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"live","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"vat","outputs":[{"internalType":"contract VatLike","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]


================================================
FILE: pymaker/abi/Dog.abi
================================================
[{"inputs":[{"internalType":"address","name":"vat_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"ilk","type":"bytes32"},{"indexed":true,"internalType":"address","name":"urn","type":"address"},{"indexed":false,"internalType":"uint256","name":"ink","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"art","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"due","type":"uint256"},{"indexed":false,"internalType":"address","name":"clip","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Bark","type":"event"},{"anonymous":false,"inputs":[],"name":"Cage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"usr","type":"address"}],"name":"Deny","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"ilk","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"rad","type":"uint256"}],"name":"Digs","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"data","type":"uint256"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"address","name":"data","type":"address"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"ilk","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"data","type":"uint256"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"ilk","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"address","name":"clip","type":"address"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"usr","type":"address"}],"name":"Rely","type":"event"},{"inputs":[],"name":"Dirt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Hole","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"address","name":"urn","type":"address"},{"internalType":"address","name":"kpr","type":"address"}],"name":"bark","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"ilk","type":"bytes32"}],"name":"chop","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"deny","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"rad","type":"uint256"}],"name":"digs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"uint256","name":"data","type":"uint256"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"uint256","name":"data","type":"uint256"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"address","name":"data","type":"address"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"address","name":"clip","type":"address"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"ilks","outputs":[{"internalType":"address","name":"clip","type":"address"},{"internalType":"uint256","name":"chop","type":"uint256"},{"internalType":"uint256","name":"hole","type":"uint256"},{"internalType":"uint256","name":"dirt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"live","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"rely","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vat","outputs":[{"internalType":"contract VatLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vow","outputs":[{"internalType":"contract VowLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]


================================================
FILE: pymaker/abi/DsrManager.abi
================================================
[{"inputs":[{"internalType":"address","name":"pot_","type":"address"},{"internalType":"address","name":"daiJoin_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Exit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Join","type":"event"},{"constant":true,"inputs":[],"name":"dai","outputs":[{"internalType":"contract GemLike","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"daiBalance","outputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"daiJoin","outputs":[{"internalType":"contract JoinLike","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"exit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"dst","type":"address"}],"name":"exitAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"join","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pieOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pot","outputs":[{"internalType":"contract PotLike","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]


================================================
FILE: pymaker/abi/DssCdpManager.abi
================================================
[{"inputs":[{"internalType":"address","name":"vat_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":true,"internalType":"address","name":"usr","type":"address"},{"indexed":true,"internalType":"bytes32","name":"arg1","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"arg2","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"usr","type":"address"},{"indexed":true,"internalType":"address","name":"own","type":"address"},{"indexed":true,"internalType":"uint256","name":"cdp","type":"uint256"}],"name":"NewCdp","type":"event"},{"constant":false,"inputs":[{"internalType":"uint256","name":"cdp","type":"uint256"},{"internalType":"address","name":"usr","type":"address"},{"internalType":"uint256","name":"ok","type":"uint256"}],"name":"cdpAllow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"cdpCan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cdpi","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address"
Download .txt
gitextract_8lkti2po/

├── .github/
│   └── workflows/
│       └── tests.yaml
├── .gitignore
├── .python-version
├── COPYING
├── Makefile
├── README.md
├── config/
│   ├── kovan-addresses.json
│   ├── mainnet-addresses.json
│   └── testnet-addresses.json
├── docker-compose.yml
├── docs/
│   ├── conf.py
│   └── index.rst
├── pymaker/
│   ├── __init__.py
│   ├── abi/
│   │   ├── Cat.abi
│   │   ├── Clipper.abi
│   │   ├── ClipperCallee.abi
│   │   ├── DSAuth.abi
│   │   ├── DSChief.abi
│   │   ├── DSEthToken.abi
│   │   ├── DSGuard.abi
│   │   ├── DSPause.abi
│   │   ├── DSProxy.abi
│   │   ├── DSProxyCache.abi
│   │   ├── DSProxyFactory.abi
│   │   ├── DSRoles.abi
│   │   ├── DSToken.abi
│   │   ├── DSValue.abi
│   │   ├── DSVault.abi
│   │   ├── DaiJoin.abi
│   │   ├── Dog.abi
│   │   ├── DsrManager.abi
│   │   ├── DssCdpManager.abi
│   │   ├── DssProxyActionsDsr.abi
│   │   ├── ERC20Token.abi
│   │   ├── ESM.abi
│   │   ├── End.abi
│   │   ├── EtherDelta.abi
│   │   ├── EtherToken.abi
│   │   ├── Exchange.abi
│   │   ├── ExchangeV2-ERC20Proxy.abi
│   │   ├── ExchangeV2.abi
│   │   ├── Flapper.abi
│   │   ├── Flipper.abi
│   │   ├── Flopper.abi
│   │   ├── GemJoin.abi
│   │   ├── GemJoin5.abi
│   │   ├── Jug.abi
│   │   ├── MakerOtcSupportMethods.abi
│   │   ├── MatchingMarket.abi
│   │   ├── OSM.abi
│   │   ├── Pit.abi
│   │   ├── Pot.abi
│   │   ├── ProxyRegistry.abi
│   │   ├── SaiTap.abi
│   │   ├── SaiTop.abi
│   │   ├── SaiTub.abi
│   │   ├── SaiVox.abi
│   │   ├── SimpleMarket.abi
│   │   ├── Spotter.abi
│   │   ├── TokenFaucet.abi
│   │   ├── TokenTransferProxy.abi
│   │   ├── TxManager.abi
│   │   ├── Vat.abi
│   │   ├── Vow.abi
│   │   ├── ZRXToken.abi
│   │   └── diff-abi.sh
│   ├── approval.py
│   ├── auctions.py
│   ├── auth.py
│   ├── cdpmanager.py
│   ├── collateral.py
│   ├── deployment.py
│   ├── dsr.py
│   ├── dsrmanager.py
│   ├── dss.py
│   ├── etherdelta.py
│   ├── feed.py
│   ├── gas.py
│   ├── governance.py
│   ├── ilk.py
│   ├── join.py
│   ├── keys.py
│   ├── lifecycle.py
│   ├── logging.py
│   ├── model.py
│   ├── numeric.py
│   ├── oasis.py
│   ├── oracles.py
│   ├── proxy.py
│   ├── reloadable_config.py
│   ├── sai.py
│   ├── shutdown.py
│   ├── sign.py
│   ├── tightly_packed.py
│   ├── token.py
│   ├── transactional.py
│   ├── util.py
│   ├── vault.py
│   ├── zrx.py
│   └── zrxv2.py
├── requirements-dev.txt
├── requirements.txt
├── setup.py
├── test-dss.sh
├── test.sh
├── tests/
│   ├── __init__.py
│   ├── abi/
│   │   ├── DaiMock.abi
│   │   ├── DaiMock.sol
│   │   ├── GemMock.abi
│   │   ├── GemMock.sol
│   │   ├── OasisMockPriceOracle.abi
│   │   └── OasisMockPriceOracle.sol
│   ├── accounts/
│   │   ├── 0_0x9596c16d7bf9323265c2f2e22f43e6c80eb3d943.json
│   │   ├── 1_0xe415482ca06eeb684ad3f758c2129fca4b1eb1f4.json
│   │   ├── 2_0x270b0e8d873e858abd698a000b0da0b94e21d84c.json
│   │   ├── 3_0x812e87be5d4198fca55cb52fa60cb46620617474.json
│   │   ├── 4_0x13314e21cd6d343ceb857073f3f6d9368919d1ef.json
│   │   ├── 5_0x176087fea5c41fc370fabbd850521bc4451690ca.json
│   │   └── pass
│   ├── config/
│   │   ├── keys/
│   │   │   └── UnlimitedChain/
│   │   │       ├── key.json
│   │   │       ├── key1.json
│   │   │       ├── key2.json
│   │   │       ├── key3.json
│   │   │       └── key4.json
│   │   └── parity-dev-constantinopole.json
│   ├── conftest.py
│   ├── dss_token.py
│   ├── helpers.py
│   ├── manual_test_async_tx.py
│   ├── manual_test_cdpmanager.py
│   ├── manual_test_dsr.py
│   ├── manual_test_goerli.py
│   ├── manual_test_mcd.py
│   ├── manual_test_node.py
│   ├── manual_test_tx_recovery.py
│   ├── manual_test_zrxv2.py
│   ├── test_approval.py
│   ├── test_auctions.py
│   ├── test_auth.py
│   ├── test_cdpmanager.py
│   ├── test_dsrmanager.py
│   ├── test_dss.py
│   ├── test_etherdelta.py
│   ├── test_feed.py
│   ├── test_gas.py
│   ├── test_general.py
│   ├── test_general2.py
│   ├── test_governance.py
│   ├── test_keys.py
│   ├── test_lifecycle.py
│   ├── test_model.py
│   ├── test_numeric.py
│   ├── test_oasis.py
│   ├── test_proxy.py
│   ├── test_reloadable_config.py
│   ├── test_sai.py
│   ├── test_savings.py
│   ├── test_shutdown.py
│   ├── test_sign.py
│   ├── test_token.py
│   ├── test_transactional.py
│   ├── test_util.py
│   ├── test_vault.py
│   ├── test_zrx.py
│   └── test_zrxv2.py
└── utils/
    └── etherdelta-client/
        ├── .gitignore
        ├── main.js
        └── package.json
Download .txt
SYMBOL INDEX (1735 symbols across 72 files)

FILE: pymaker/__init__.py
  function web3_via_http (line 56) | def web3_via_http(endpoint_uri: str, timeout=60, http_pool_size=20):
  class NonceCalculation (line 73) | class NonceCalculation(Enum):
  function _get_nonce_calc (line 80) | def _get_nonce_calc(web3: Web3) -> NonceCalculation:
  function register_filter_thread (line 100) | def register_filter_thread(filter_thread):
  function any_filter_thread_present (line 104) | def any_filter_thread_present() -> bool:
  function all_filter_threads_alive (line 108) | def all_filter_threads_alive() -> bool:
  function filter_thread_alive (line 112) | def filter_thread_alive(filter_thread) -> bool:
  function stop_all_filter_threads (line 118) | def stop_all_filter_threads():
  function _track_status (line 126) | def _track_status(f):
  class Address (line 145) | class Address:
    method __init__ (line 157) | def __init__(self, address):
    method zero (line 164) | def zero():
    method as_bytes (line 167) | def as_bytes(self) -> bytes:
    method __str__ (line 171) | def __str__(self):
    method __repr__ (line 174) | def __repr__(self):
    method __hash__ (line 177) | def __hash__(self):
    method __eq__ (line 180) | def __eq__(self, other):
    method __lt__ (line 184) | def __lt__(self, other):
  class Contract (line 189) | class Contract:
    method _deploy (line 193) | def _deploy(web3: Web3, abi: list, bytecode: str, args: list) -> Address:
    method _get_contract (line 206) | def _get_contract(web3: Web3, abi: list, address: Address):
    method _past_events (line 216) | def _past_events(self, contract, event, cls, number_of_past_blocks, ev...
    method _past_events_in_block_range (line 221) | def _past_events_in_block_range(self, contract, event, cls, from_block...
    method _load_abi (line 244) | def _load_abi(package, resource) -> list:
    method _load_bin (line 248) | def _load_bin(package, resource) -> str:
  class Calldata (line 252) | class Calldata:
    method __init__ (line 258) | def __init__(self, value):
    method from_signature (line 270) | def from_signature(cls, web3: Web3, fn_sign: str, fn_args: list):
    method from_contract_abi (line 291) | def from_contract_abi(cls, web3: Web3, fn_sign: str, fn_args: list, co...
    method as_bytes (line 305) | def as_bytes(self) -> bytes:
    method __str__ (line 309) | def __str__(self):
    method __repr__ (line 312) | def __repr__(self):
    method __hash__ (line 315) | def __hash__(self):
    method __eq__ (line 318) | def __eq__(self, other):
  class Invocation (line 323) | class Invocation(object):
    method __init__ (line 330) | def __init__(self, address: Address, calldata: Calldata):
  class Receipt (line 337) | class Receipt:
    method __init__ (line 353) | def __init__(self, receipt):
    method logs (line 409) | def logs(self):
  class TransactStatus (line 413) | class TransactStatus(Enum):
  function get_pending_transactions (line 419) | def get_pending_transactions(web3: Web3, address: Address = None) -> list:
  class Transact (line 446) | class Transact:
    method __init__ (line 452) | def __init__(self,
    method _get_receipt (line 489) | def _get_receipt(self, transaction_hash: str) -> Optional[Receipt]:
    method _as_dict (line 500) | def _as_dict(self, dict_or_none) -> dict:
    method _gas (line 506) | def _gas(self, gas_estimate: int, **kwargs) -> int:
    method _func (line 517) | def _func(self, from_account: str, gas: int, gas_price: Optional[int],...
    method _contract_function (line 538) | def _contract_function(self):
    method name (line 547) | def name(self) -> str:
    method estimated_gas (line 567) | def estimated_gas(self, from_address: Address) -> int:
    method transact (line 595) | def transact(self, **kwargs) -> Optional[Receipt]:
    method transact_async (line 620) | async def transact_async(self, **kwargs) -> Optional[Receipt]:
    method invocation (line 782) | def invocation(self) -> Invocation:
  class RecoveredTransact (line 796) | class RecoveredTransact(Transact):
    method __init__ (line 802) | def __init__(self, web3: Web3,
    method name (line 819) | def name(self):
    method transact_async (line 823) | async def transact_async(self, **kwargs) -> Optional[Receipt]:
    method cancel (line 827) | def cancel(self, gas_price: GasPrice):
    method cancel_async (line 830) | async def cancel_async(self, gas_price: GasPrice):
  class Transfer (line 864) | class Transfer:
    method __init__ (line 876) | def __init__(self, token_address: Address, from_address: Address, to_a...
    method __eq__ (line 886) | def __eq__(self, other):
    method __hash__ (line 893) | def __hash__(self):
  function eth_transfer (line 897) | def eth_transfer(web3: Web3, to: Address, amount: Wad) -> Transact:

FILE: pymaker/approval.py
  function directly (line 27) | def directly(**kwargs):
  function via_tx_manager (line 47) | def via_tx_manager(tx_manager: TxManager, **kwargs):
  function hope_directly (line 67) | def hope_directly(**kwargs):

FILE: pymaker/auctions.py
  function toBytes (line 36) | def toBytes(string: str):
  class AuctionContract (line 44) | class AuctionContract(Contract):
    method __init__ (line 46) | def __init__(self, web3: Web3, address: Address, abi: list):
    method approve (line 66) | def approve(self, source: Address, approval_function):
    method wards (line 83) | def wards(self, address: Address) -> bool:
    method vat (line 88) | def vat(self) -> Address:
    method get_past_lognotes (line 95) | def get_past_lognotes(self, abi: list, from_block: int, to_block: int ...
    method parse_event (line 131) | def parse_event(self, event):
  class DealableAuctionContract (line 135) | class DealableAuctionContract(AuctionContract):
    class DealLog (line 138) | class DealLog:
      method __init__ (line 139) | def __init__(self, lognote: LogNote):
      method __repr__ (line 146) | def __repr__(self):
    method __init__ (line 149) | def __init__(self, web3: Web3, address: Address, abi: list, bids: call...
    method active_auctions (line 156) | def active_auctions(self) -> list:
    method beg (line 168) | def beg(self) -> Wad:
    method ttl (line 176) | def ttl(self) -> int:
    method tau (line 184) | def tau(self) -> int:
    method kicks (line 192) | def kicks(self) -> int:
    method deal (line 200) | def deal(self, id: int) -> Transact:
    method tick (line 205) | def tick(self, id: int) -> Transact:
  class Flipper (line 212) | class Flipper(DealableAuctionContract):
    class Bid (line 235) | class Bid:
      method __init__ (line 236) | def __init__(self, id: int, bid: Rad, lot: Wad, guy: Address, tic: i...
      method __repr__ (line 258) | def __repr__(self):
    class KickLog (line 261) | class KickLog:
      method __init__ (line 262) | def __init__(self, log):
      method __repr__ (line 273) | def __repr__(self):
    class TendLog (line 276) | class TendLog:
      method __init__ (line 277) | def __init__(self, lognote: LogNote):
      method __repr__ (line 285) | def __repr__(self):
    class DentLog (line 288) | class DentLog:
      method __init__ (line 289) | def __init__(self, lognote: LogNote):
      method __repr__ (line 297) | def __repr__(self):
    method __init__ (line 300) | def __init__(self, web3: Web3, address: Address):
    method bids (line 303) | def bids(self, id: int) -> Bid:
    method tend (line 326) | def tend(self, id: int, lot: Wad, bid: Rad) -> Transact:
    method dent (line 333) | def dent(self, id: int, lot: Wad, bid: Rad) -> Transact:
    method past_logs (line 340) | def past_logs(self, from_block: int, to_block: int = None, chunk_size=...
    method parse_event (line 357) | def parse_event(self, event):
    method __repr__ (line 367) | def __repr__(self):
  class Flapper (line 371) | class Flapper(DealableAuctionContract):
    class Bid (line 393) | class Bid:
      method __init__ (line 394) | def __init__(self, id: int, bid: Wad, lot: Rad, guy: Address, tic: i...
      method __repr__ (line 409) | def __repr__(self):
    class KickLog (line 412) | class KickLog:
      method __init__ (line 413) | def __init__(self, log):
      method __repr__ (line 421) | def __repr__(self):
    class TendLog (line 424) | class TendLog:
      method __init__ (line 425) | def __init__(self, lognote: LogNote):
      method __repr__ (line 433) | def __repr__(self):
    method __init__ (line 436) | def __init__(self, web3: Web3, address: Address):
    method live (line 439) | def live(self) -> bool:
    method bids (line 442) | def bids(self, id: int) -> Bid:
    method tend (line 462) | def tend(self, id: int, lot: Rad, bid: Wad) -> Transact:
    method yank (line 469) | def yank(self, id: int) -> Transact:
    method past_logs (line 475) | def past_logs(self, from_block: int, to_block: int = None, chunk_size=...
    method parse_event (line 490) | def parse_event(self, event):
    method __repr__ (line 500) | def __repr__(self):
  class Flopper (line 504) | class Flopper(DealableAuctionContract):
    class Bid (line 526) | class Bid:
      method __init__ (line 527) | def __init__(self, id: int, bid: Rad, lot: Wad, guy: Address, tic: i...
      method __repr__ (line 542) | def __repr__(self):
    class KickLog (line 545) | class KickLog:
      method __init__ (line 546) | def __init__(self, log):
      method __repr__ (line 555) | def __repr__(self):
    class DentLog (line 558) | class DentLog:
      method __init__ (line 559) | def __init__(self, lognote: LogNote):
      method __repr__ (line 567) | def __repr__(self):
    method __init__ (line 570) | def __init__(self, web3: Web3, address: Address):
    method live (line 576) | def live(self) -> bool:
    method pad (line 579) | def pad(self) -> Wad:
    method bids (line 584) | def bids(self, id: int) -> Bid:
    method dent (line 604) | def dent(self, id: int, lot: Wad, bid: Rad) -> Transact:
    method yank (line 611) | def yank(self, id: int) -> Transact:
    method past_logs (line 617) | def past_logs(self, from_block: int, to_block: int = None, chunk_size=...
    method parse_event (line 632) | def parse_event(self, event):
    method __repr__ (line 642) | def __repr__(self):
  class Clipper (line 646) | class Clipper(AuctionContract):
    class KickLog (line 660) | class KickLog:
      method __init__ (line 661) | def __init__(self, log):
      method __repr__ (line 673) | def __repr__(self):
    class TakeLog (line 676) | class TakeLog:
      method __init__ (line 677) | def __init__(self, log, sender):
      method __repr__ (line 690) | def __repr__(self):
    class RedoLog (line 693) | class RedoLog(KickLog):
      method __repr__ (line 695) | def __repr__(self):
    class Sale (line 698) | class Sale:
      method __init__ (line 699) | def __init__(self, id: int, pos: int, tab: Rad, lot: Wad, usr: Addre...
      method __repr__ (line 716) | def __repr__(self):
    method __init__ (line 719) | def __init__(self, web3: Web3, address: Address):
    method active_auctions (line 740) | def active_auctions(self) -> list:
    method ilk_name (line 749) | def ilk_name(self) -> str:
    method buf (line 753) | def buf(self) -> Ray:
    method tail (line 757) | def tail(self) -> int:
    method cusp (line 761) | def cusp(self) -> Ray:
    method chip (line 765) | def chip(self) -> Wad:
    method tip (line 769) | def tip(self) -> Rad:
    method chost (line 773) | def chost(self) -> Rad:
    method kicks (line 777) | def kicks(self) -> int:
    method active_count (line 781) | def active_count(self) -> int:
    method status (line 785) | def status(self, id: int) -> (bool, Ray, Wad, Rad):
    method sales (line 796) | def sales(self, id: int) -> Sale:
    method validate_take (line 815) | def validate_take(self, id: int, amt: Wad, max: Ray, our_address: Addr...
    method take (line 848) | def take(self, id: int, amt: Wad, max: Ray, who: Address = None, data=...
    method redo (line 869) | def redo(self, id: int, kpr: Address = None) -> Transact:
    method upchost (line 884) | def upchost(self):
    method past_logs (line 888) | def past_logs(self, from_block: int, to_block: int = None, chunk_size=...
    method parse_event (line 903) | def parse_event(self, event):
    method _get_sender_for_eventlog (line 919) | def _get_sender_for_eventlog(self, event_data) -> Address:
    method __repr__ (line 924) | def __repr__(self):

FILE: pymaker/auth.py
  class DSGuard (line 24) | class DSGuard(Contract):
    method __init__ (line 40) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 49) | def deploy(web3: Web3):
    method permit (line 52) | def permit(self, src, dst, sig: bytes) -> Transact:
    method __repr__ (line 77) | def __repr__(self):
  class DSAuth (line 82) | class DSAuth(Contract):
    method __init__ (line 87) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 96) | def deploy(web3: Web3):
    method get_owner (line 99) | def get_owner(self) -> Address:
    method set_owner (line 102) | def set_owner(self, owner: Address) -> Transact:
    method set_authority (line 108) | def set_authority(self, ds_authority: Address):

FILE: pymaker/cdpmanager.py
  class CdpManager (line 26) | class CdpManager(Contract):
    method __init__ (line 35) | def __init__(self, web3: Web3, address: Address):
    method open (line 44) | def open(self, ilk: Ilk, address: Address) -> Transact:
    method urn (line 51) | def urn(self, cdpid: int) -> Urn:
    method owns (line 61) | def owns(self, cdpid: int) -> Address:
    method ilk (line 68) | def ilk(self, cdpid: int) -> Ilk:
    method first (line 75) | def first(self, address: Address) -> int:
    method last (line 82) | def last(self, address: Address) -> int:
    method count (line 89) | def count(self, address: Address) -> int:
    method __repr__ (line 96) | def __repr__(self):

FILE: pymaker/collateral.py
  class Collateral (line 32) | class Collateral:
    method __init__ (line 38) | def __init__(self, ilk: Ilk, gem: ERC20Token, adapter: GemJoin, auctio...
    method approve (line 59) | def approve(self, usr: Address, **kwargs):

FILE: pymaker/deployment.py
  function deploy_contract (line 48) | def deploy_contract(web3: Web3, contract_name: str, args: Optional[list]...
  class Deployment (line 73) | class Deployment:
    method __init__ (line 80) | def __init__(self):
    method reset (line 138) | def reset(self):
    method time_travel_by (line 143) | def time_travel_by(self, seconds: int):
  class DssDeployment (line 148) | class DssDeployment:
    class Config (line 160) | class Config:
      method __init__ (line 161) | def __init__(self, pause: DSPause, vat: Vat, vow: Vow, jug: Jug, cat...
      method from_json (line 190) | def from_json(web3: Web3, conf: str):
      method _infer_collaterals_from_addresses (line 264) | def _infer_collaterals_from_addresses(keys: []) -> List:
      method to_dict (line 277) | def to_dict(self) -> dict:
      method to_json (line 320) | def to_json(self) -> str:
    method __init__ (line 323) | def __init__(self, web3: Web3, config: Config):
    method from_json (line 353) | def from_json(web3: Web3, conf: str):
    method to_json (line 356) | def to_json(self) -> str:
    method from_node (line 360) | def from_node(web3: Web3):
    method from_network (line 368) | def from_network(web3: Web3, network: str):
    method approve_dai (line 377) | def approve_dai(self, usr: Address, **kwargs):
    method active_auctions (line 391) | def active_auctions(self) -> dict:
    method __repr__ (line 408) | def __repr__(self):

FILE: pymaker/dsr.py
  class Dsr (line 30) | class Dsr:
    method __init__ (line 36) | def __init__(self, mcd: DssDeployment, owner: Address):
    method has_proxy (line 43) | def has_proxy(self) -> bool:
    method get_proxy (line 46) | def get_proxy(self) -> DSProxy:
    method build_proxy (line 49) | def build_proxy(self) -> Transact:
    method chi (line 52) | def chi(self) -> Ray:
    method get_total_dai (line 55) | def get_total_dai(self) -> Wad:
    method dsr (line 58) | def dsr(self) -> Ray:
    method get_balance (line 61) | def get_balance(self, proxy: Address) -> Wad:
    method join (line 74) | def join(self, amount: Wad, proxy: DSProxy) -> Transact:
    method exit (line 89) | def exit(self, amount: Wad, proxy: DSProxy) -> Transact:
    method exit_all (line 104) | def exit_all(self, proxy: DSProxy) -> Transact:

FILE: pymaker/dsrmanager.py
  class DsrManager (line 28) | class DsrManager(Contract):
    method __init__ (line 39) | def __init__(self, web3: Web3, address: Address):
    method pot (line 47) | def pot(self) -> Pot:
    method dai (line 51) | def dai(self) -> DSToken:
    method dai_adapter (line 55) | def dai_adapter(self) -> DaiJoin:
    method supply (line 59) | def supply(self) -> Wad:
    method pie_of (line 63) | def pie_of(self, usr: Address) -> Wad:
    method dai_of (line 69) | def dai_of(self, usr: Address) -> Rad:
    method join (line 83) | def join(self, dst: Address, dai: Wad) -> Transact:
    method exit (line 91) | def exit(self, dst: Address, dai: Wad) -> Transact:
    method exitAll (line 99) | def exitAll(self, dst: Address) -> Transact:
    method __repr__ (line 105) | def __repr__(self):

FILE: pymaker/dss.py
  class Urn (line 35) | class Urn:
    method __init__ (line 40) | def __init__(self, address: Address, ilk: Ilk = None, ink: Wad = None,...
    method toBytes (line 51) | def toBytes(self):
    method fromBytes (line 56) | def fromBytes(urn: bytes):
    method __eq__ (line 62) | def __eq__(self, other):
    method __repr__ (line 67) | def __repr__(self):
  class Vat (line 80) | class Vat(Contract):
    class LogFrob (line 87) | class LogFrob:
      method __init__ (line 88) | def __init__(self, lognote: LogNote):
      method __repr__ (line 100) | def __repr__(self):
    class LogMove (line 104) | class LogMove:
      method __init__ (line 105) | def __init__(self, lognote: LogNote):
      method __repr__ (line 114) | def __repr__(self):
    class LogFork (line 118) | class LogFork:
      method __init__ (line 119) | def __init__(self, lognote: LogNote):
      method __repr__ (line 130) | def __repr__(self):
    method __init__ (line 136) | def __init__(self, web3: Web3, address: Address):
    method init (line 144) | def init(self, ilk: Ilk) -> Transact:
    method live (line 149) | def live(self) -> bool:
    method wards (line 152) | def wards(self, address: Address):
    method hope (line 157) | def hope(self, address: Address):
    method can (line 162) | def can(self, sender: Address, usr: Address):
    method ilk (line 168) | def ilk(self, name: str) -> Ilk:
    method gem (line 177) | def gem(self, ilk: Ilk, urn: Address) -> Wad:
    method dai (line 183) | def dai(self, urn: Address) -> Rad:
    method sin (line 188) | def sin(self, urn: Address) -> Rad:
    method urn (line 193) | def urn(self, ilk: Ilk, address: Address) -> Urn:
    method debt (line 200) | def debt(self) -> Rad:
    method vice (line 203) | def vice(self) -> Rad:
    method line (line 206) | def line(self) -> Rad:
    method flux (line 210) | def flux(self, ilk: Ilk, src: Address, dst: Address, wad: Wad) -> Tran...
    method move (line 227) | def move(self, src: Address, dst: Address, rad: Rad) -> Transact:
    method fork (line 242) | def fork(self, ilk: Ilk, src: Address, dst: Address, dink: Wad, dart: ...
    method frob (line 261) | def frob(self, ilk: Ilk, urn_address: Address, dink: Wad, dart: Wad, c...
    method get_wipe_all_dart (line 297) | def get_wipe_all_dart(self, ilk: Ilk, urn: Address) -> Wad:
    method validate_frob (line 309) | def validate_frob(self, ilk: Ilk, address: Address, dink: Wad, dart: W...
    method past_frobs (line 363) | def past_frobs(self, from_block: int, to_block: int = None, ilk: Ilk =...
    method past_logs (line 376) | def past_logs(self, from_block: int, to_block: int = None, ilk: Ilk = ...
    method heal (line 446) | def heal(self, vice: Rad) -> Transact:
    method __eq__ (line 451) | def __eq__(self, other):
    method __repr__ (line 455) | def __repr__(self):
  class Spotter (line 459) | class Spotter(Contract):
    method __init__ (line 469) | def __init__(self, web3: Web3, address: Address):
    method poke (line 477) | def poke(self, ilk: Ilk) -> Transact:
    method vat (line 482) | def vat(self) -> Address:
    method par (line 485) | def par(self) -> Ray:
    method mat (line 488) | def mat(self, ilk: Ilk) -> Ray:
    method __repr__ (line 494) | def __repr__(self):
  class Vow (line 498) | class Vow(Contract):
    method __init__ (line 508) | def __init__(self, web3: Web3, address: Address):
    method rely (line 517) | def rely(self, guy: Address) -> Transact:
    method live (line 522) | def live(self) -> bool:
    method flapper (line 525) | def flapper(self) -> Address:
    method flopper (line 528) | def flopper(self) -> Address:
    method sin (line 531) | def sin(self) -> Rad:
    method sin_of (line 534) | def sin_of(self, era: int) -> Rad:
    method ash (line 537) | def ash(self) -> Rad:
    method woe (line 540) | def woe(self) -> Rad:
    method wait (line 543) | def wait(self) -> int:
    method dump (line 546) | def dump(self) -> Wad:
    method sump (line 549) | def sump(self) -> Rad:
    method bump (line 552) | def bump(self) -> Rad:
    method hump (line 555) | def hump(self) -> Rad:
    method flog (line 558) | def flog(self, era: int) -> Transact:
    method heal (line 563) | def heal(self, rad: Rad) -> Transact:
    method kiss (line 569) | def kiss(self, rad: Rad) -> Transact:
    method flop (line 574) | def flop(self) -> Transact:
    method flap (line 580) | def flap(self) -> Transact:
    method __repr__ (line 586) | def __repr__(self):
  class Jug (line 590) | class Jug(Contract):
    method __init__ (line 599) | def __init__(self, web3: Web3, address: Address):
    method init (line 609) | def init(self, ilk: Ilk) -> Transact:
    method wards (line 614) | def wards(self, address: Address):
    method drip (line 619) | def drip(self, ilk: Ilk) -> Transact:
    method base (line 624) | def base(self) -> Ray:
    method duty (line 627) | def duty(self, ilk: Ilk) -> Ray:
    method rho (line 632) | def rho(self, ilk: Ilk) -> int:
    method __repr__ (line 637) | def __repr__(self):
  class Cat (line 641) | class Cat(Contract):
    class LogBite (line 649) | class LogBite:
      method __init__ (line 650) | def __init__(self, log):
      method era (line 660) | def era(self, web3: Web3):
      method __eq__ (line 663) | def __eq__(self, other):
      method __repr__ (line 667) | def __repr__(self):
    method __init__ (line 673) | def __init__(self, web3: Web3, address: Address):
    method live (line 683) | def live(self) -> bool:
    method can_bite (line 686) | def can_bite(self, ilk: Ilk, urn: Urn) -> bool:
    method bite (line 721) | def bite(self, ilk: Ilk, urn: Urn) -> Transact:
    method chop (line 740) | def chop(self, ilk: Ilk) -> Wad:
    method dunk (line 746) | def dunk(self, ilk: Ilk) -> Rad:
    method flipper (line 752) | def flipper(self, ilk: Ilk) -> Address:
    method box (line 758) | def box(self) -> Rad:
    method litter (line 761) | def litter(self) -> Rad:
    method past_bites (line 764) | def past_bites(self, number_of_past_blocks: int, event_filter: dict = ...
    method __repr__ (line 781) | def __repr__(self):
  class Dog (line 785) | class Dog(Contract):
    class LogBark (line 793) | class LogBark:
      method __init__ (line 794) | def __init__(self, log):
      method era (line 804) | def era(self, web3: Web3):
      method __eq__ (line 807) | def __eq__(self, other):
      method __repr__ (line 811) | def __repr__(self):
    method __init__ (line 817) | def __init__(self, web3: Web3, address: Address):
    method live (line 829) | def live(self) -> bool:
    method clipper (line 832) | def clipper(self, ilk: Ilk) -> Address:
    method chop (line 838) | def chop(self, ilk: Ilk) -> Wad:
    method hole (line 843) | def hole(self, ilk: Ilk) -> Rad:
    method dirt (line 848) | def dirt(self, ilk: Ilk) -> Rad:
    method dog_hole (line 853) | def dog_hole(self) -> Rad:
    method dog_dirt (line 856) | def dog_dirt(self) -> Rad:
    method bark (line 859) | def bark(self, ilk: Ilk, urn: Urn, kpr: Address = None) -> Transact:
    method past_barks (line 883) | def past_barks(self, number_of_past_blocks: int, event_filter: dict = ...
  class Pot (line 901) | class Pot(Contract):
    method __init__ (line 910) | def __init__(self, web3: Web3, address: Address):
    method approve (line 918) | def approve(self, source: Address, approval_function, **kwargs):
    method pie_of (line 925) | def pie_of(self, address: Address) -> Wad:
    method pie (line 929) | def pie(self) -> Wad:
    method dsr (line 933) | def dsr(self) -> Ray:
    method chi (line 937) | def chi(self) -> Ray:
    method rho (line 941) | def rho(self) -> datetime:
    method drip (line 945) | def drip(self) -> Transact:
    method __repr__ (line 950) | def __repr__(self):
  class TokenFaucet (line 954) | class TokenFaucet(Contract):
    method __init__ (line 963) | def __init__(self, web3: Web3, address: Address):
    method gulp (line 971) | def gulp(self, address: Address):

FILE: pymaker/etherdelta.py
  class Order (line 37) | class Order:
    method __init__ (line 52) | def __init__(self, ether_delta, maker: Address, pay_token: Address, pa...
    method sell_to_buy_price (line 79) | def sell_to_buy_price(self) -> Wad:
    method buy_to_sell_price (line 83) | def buy_to_sell_price(self) -> Wad:
    method remaining_buy_amount (line 87) | def remaining_buy_amount(self) -> Wad:
    method remaining_sell_amount (line 91) | def remaining_sell_amount(self) -> Wad:
    method from_json (line 95) | def from_json(ether_delta, data: dict):
    method to_json (line 102) | def to_json(self) -> dict:
    method __eq__ (line 115) | def __eq__(self, other):
    method __hash__ (line 128) | def __hash__(self):
    method __str__ (line 140) | def __str__(self):
    method __repr__ (line 145) | def __repr__(self):
  class LogTrade (line 149) | class LogTrade:
    method __init__ (line 150) | def __init__(self, log):
    method __repr__ (line 159) | def __repr__(self):
  class EtherDelta (line 163) | class EtherDelta(Contract):
    method deploy (line 180) | def deploy(web3: Web3,
    method __init__ (line 205) | def __init__(self, web3: Web3, address: Address):
    method approve (line 213) | def approve(self, tokens: List[ERC20Token], approval_function):
    method admin (line 229) | def admin(self) -> Address:
    method fee_account (line 237) | def fee_account(self) -> Address:
    method account_levels_addr (line 245) | def account_levels_addr(self) -> Address:
    method fee_make (line 253) | def fee_make(self) -> Wad:
    method fee_take (line 261) | def fee_take(self) -> Wad:
    method fee_rebate (line 269) | def fee_rebate(self) -> Wad:
    method past_trade (line 279) | def past_trade(self, number_of_past_blocks: int, event_filter: dict = ...
    method deposit (line 296) | def deposit(self, amount: Wad) -> Transact:
    method withdraw (line 308) | def withdraw(self, amount: Wad) -> Transact:
    method balance_of (line 322) | def balance_of(self, user: Address) -> Wad:
    method deposit_token (line 334) | def deposit_token(self, token: Address, amount: Wad) -> Transact:
    method withdraw_token (line 353) | def withdraw_token(self, token: Address, amount: Wad) -> Transact:
    method balance_of_token (line 370) | def balance_of_token(self, token: Address, user: Address) -> Wad:
    method create_order (line 384) | def create_order(self,
    method amount_available (line 433) | def amount_available(self, order: Order) -> Wad:
    method amount_filled (line 458) | def amount_filled(self, order: Order) -> Wad:
    method trade (line 486) | def trade(self, order: Order, amount: Wad) -> Transact:
    method can_trade (line 519) | def can_trade(self, order: Order, amount: Wad) -> bool:
    method cancel_order (line 548) | def cancel_order(self, order: Order) -> Transact:
    method random_nonce (line 573) | def random_nonce():
    method __repr__ (line 576) | def __repr__(self):
  class EtherDeltaApi (line 580) | class EtherDeltaApi:
    method __init__ (line 596) | def __init__(self,
    method publish_order (line 617) | def publish_order(self, order: Order):
    method __repr__ (line 653) | def __repr__(self):

FILE: pymaker/feed.py
  class DSValue (line 24) | class DSValue(DSAuth):
    method deploy (line 52) | def deploy(web3: Web3):
    method __init__ (line 55) | def __init__(self, web3: Web3, address: Address):
    method has_value (line 63) | def has_value(self) -> bool:
    method read (line 71) | def read(self) -> bytes:
    method read_as_hex (line 81) | def read_as_hex(self) -> str:
    method read_as_int (line 91) | def read_as_int(self) -> int:
    method poke (line 104) | def poke(self, new_value: bytes) -> Transact:
    method poke_with_int (line 117) | def poke_with_int(self, new_value: int) -> Transact:
    method void (line 135) | def void(self) -> Transact:
    method __repr__ (line 143) | def __repr__(self):

FILE: pymaker/gas.py
  class GasPrice (line 23) | class GasPrice(object):
    method get_gas_price (line 41) | def get_gas_price(self, time_elapsed: int) -> Optional[int]:
  class DefaultGasPrice (line 61) | class DefaultGasPrice(GasPrice):
    method get_gas_price (line 68) | def get_gas_price(self, time_elapsed: int) -> Optional[int]:
  class NodeAwareGasPrice (line 72) | class NodeAwareGasPrice(GasPrice):
    method __init__ (line 78) | def __init__(self, web3: Web3):
    method get_gas_price (line 84) | def get_gas_price(self, time_elapsed: int) -> Optional[int]:
    method get_node_gas_price (line 89) | def get_node_gas_price(self):
  class FixedGasPrice (line 93) | class FixedGasPrice(GasPrice):
    method __init__ (line 103) | def __init__(self, gas_price: int):
    method update_gas_price (line 107) | def update_gas_price(self, new_gas_price: int):
    method get_gas_price (line 124) | def get_gas_price(self, time_elapsed: int) -> Optional[int]:
  class IncreasingGasPrice (line 129) | class IncreasingGasPrice(GasPrice):
    method __init__ (line 142) | def __init__(self, initial_price: int, increase_by: int, every_secs: i...
    method get_gas_price (line 158) | def get_gas_price(self, time_elapsed: int) -> Optional[int]:
  class GeometricGasPrice (line 168) | class GeometricGasPrice(GasPrice):
    method __init__ (line 181) | def __init__(self, initial_price: int, every_secs: int, coefficient=1....
    method get_gas_price (line 196) | def get_gas_price(self, time_elapsed: int) -> Optional[int]:

FILE: pymaker/governance.py
  class DSPause (line 29) | class DSPause(Contract):
    class Plan (line 40) | class Plan:
      method __init__ (line 41) | def __init__(self, usr: Address, fax: bytes, eta: datetime):
    method __init__ (line 60) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 69) | def deploy(web3: Web3, delay: int, owner: Address, ds_auth: DSAuth):
    method drop (line 77) | def drop(self, plan: Plan):
    method exec (line 80) | def exec(self, plan: Plan) -> Transact:
    method _transact (line 83) | def _transact(self, plan: Plan, function_name: str) -> Transact:
  class DSRoles (line 92) | class DSRoles(Contract):
    method __init__ (line 106) | def __init__(self, web3: Web3, address: Address):
    method is_root_user (line 114) | def is_root_user(self, who: Address) -> bool:
    method set_root_user (line 119) | def set_root_user(self, who: Address, enabled=True) -> Transact:
    method has_user_role (line 125) | def has_user_role(self, who: Address, role: int) -> bool:
    method set_user_role (line 132) | def set_user_role(self, who: Address, role: int, enabled=True) -> Tran...
  class Etch (line 141) | class Etch:
    method __init__ (line 142) | def __init__(self, log):
    method __repr__ (line 149) | def __repr__(self):
  class DSChief (line 153) | class DSChief(Contract):
    method __init__ (line 167) | def __init__(self, web3: Web3, address: Address):
    method live (line 175) | def live(self) -> bool:
    method iou (line 178) | def iou(self) -> DSToken:
    method get_votes (line 181) | def get_votes(self, address):
    method get_yay (line 184) | def get_yay(self, slate, position) -> str:
    method get_deposits (line 187) | def get_deposits(self, address) -> Wad:
    method get_approvals (line 190) | def get_approvals(self, address) -> Wad:
    method get_hat (line 193) | def get_hat(self) -> Address:
    method get_max_yays (line 196) | def get_max_yays(self) -> int:
    method launch (line 199) | def launch(self) -> Transact:
    method lock (line 202) | def lock(self, amount: Wad) -> Transact:
    method free (line 207) | def free(self, amount: Wad) -> Transact:
    method etch (line 212) | def etch(self, yays: List) -> Transact:
    method vote_yays (line 217) | def vote_yays(self, yays: List) -> Transact:
    method vote_etch (line 222) | def vote_etch(self, etch: Etch) -> Transact:
    method lift (line 227) | def lift(self, whom: Address) -> Transact:
    method past_etch (line 232) | def past_etch(self, number_of_past_blocks: int, event_filter: dict = N...
    method past_etch_in_range (line 249) | def past_etch_in_range(self, from_block: int, to_block: int, event_fil...

FILE: pymaker/ilk.py
  class Ilk (line 24) | class Ilk:
    method __init__ (line 30) | def __init__(self, name: str, rate: Optional[Ray] = None,
    method toBytes (line 52) | def toBytes(self):
    method fromBytes (line 56) | def fromBytes(ilk: bytes):
    method __eq__ (line 62) | def __eq__(self, other):
    method __repr__ (line 73) | def __repr__(self):

FILE: pymaker/join.py
  class Join (line 31) | class Join(Contract):
    method __init__ (line 32) | def __init__(self, web3: Web3, address: Address):
    method approve (line 41) | def approve(self, approval_function, source: Address):
    method approve_token (line 47) | def approve_token(self, approval_function, **kwargs):
    method join (line 50) | def join(self, usr: Address, value: Wad) -> Transact:
    method exit (line 57) | def exit(self, usr: Address, value: Wad) -> Transact:
  class DaiJoin (line 65) | class DaiJoin(Join):
    method __init__ (line 74) | def __init__(self, web3: Web3, address: Address):
    method dai (line 78) | def dai(self) -> DSToken:
  class GemJoin (line 83) | class GemJoin(Join):
    method __init__ (line 92) | def __init__(self, web3: Web3, address: Address):
    method ilk (line 96) | def ilk(self):
    method gem (line 99) | def gem(self) -> DSToken:
    method dec (line 103) | def dec(self) -> int:
  class GemJoin5 (line 107) | class GemJoin5(GemJoin):
    method __init__ (line 115) | def __init__(self, web3: Web3, address: Address):
    method dec (line 119) | def dec(self) -> int:

FILE: pymaker/keys.py
  function register_keys (line 30) | def register_keys(web3: Web3, keys: Optional[list]):
  function register_key (line 35) | def register_key(web3: Web3, key: str):
  function register_key_file (line 46) | def register_key_file(web3: Web3, key_file: str, pass_file: Optional[str...
  function get_private_key (line 62) | def get_private_key(web3: Web3, key: str):
  function register_private_key (line 83) | def register_private_key(web3: Web3, private_key):

FILE: pymaker/lifecycle.py
  function trigger_event (line 33) | def trigger_event(event: threading.Event):
  class Lifecycle (line 39) | class Lifecycle:
    method __init__ (line 80) | def __init__(self, web3: Web3 = None):
    method __enter__ (line 99) | def __enter__(self):
    method __exit__ (line 102) | def __exit__(self, exc_type, exc_val, exc_tb):
    method _wait_for_init (line 191) | def _wait_for_init(self):
    method _check_account_unlocked (line 210) | def _check_account_unlocked(self):
    method wait_for_sync (line 218) | def wait_for_sync(self, wait_for_sync: bool):
    method initial_delay (line 223) | def initial_delay(self, initial_delay: int):
    method wait_for (line 237) | def wait_for(self, initial_check, max_wait: int):
    method on_startup (line 253) | def on_startup(self, callback):
    method on_shutdown (line 264) | def on_shutdown(self, callback):
    method terminate (line 275) | def terminate(self, message=None):
    method on_block (line 281) | def on_block(self, callback):
    method on_event (line 293) | def on_event(self, event: threading.Event, min_frequency_in_seconds: i...
    method every (line 309) | def every(self, frequency_in_seconds: int, callback):
    method _sigint_sigterm_handler (line 318) | def _sigint_sigterm_handler(self, sig, frame):
    method _start_watching_blocks (line 325) | def _start_watching_blocks(self):
    method _start_thread_safely (line 373) | def _start_thread_safely(self, t: threading.Thread):
    method _start_every_timers (line 384) | def _start_every_timers(self):
    method _start_every_timer (line 397) | def _start_every_timer(self, idx: int, frequency_in_seconds: int, call...
    method _start_event_timer (line 425) | def _start_event_timer(self, idx: int, event: threading.Event, min_fre...
    method _main_loop (line 459) | def _main_loop(self):

FILE: pymaker/logging.py
  class LogNote (line 27) | class LogNote:
    method __init__ (line 28) | def __init__(self, log):
    method from_event (line 40) | def from_event(cls, event: dict, contract_abi: list):
    method get_bytes_at_index (line 53) | def get_bytes_at_index(self, index: int) -> bytes:
    method __eq__ (line 61) | def __eq__(self, other):
    method __repr__ (line 65) | def __repr__(self):

FILE: pymaker/model.py
  class Token (line 25) | class Token:
    method __init__ (line 26) | def __init__(self, name: str, address: Optional[Address], decimals: int):
    method normalize_amount (line 37) | def normalize_amount(self, amount: Wad) -> Wad:
    method unnormalize_amount (line 42) | def unnormalize_amount(self, amount: Wad) -> Wad:
    method is_eth (line 47) | def is_eth(self) -> bool:
    method __eq__ (line 50) | def __eq__(self, other):
    method __hash__ (line 56) | def __hash__(self):
    method __str__ (line 59) | def __str__(self):
    method __repr__ (line 62) | def __repr__(self):
  class TokenConfig (line 66) | class TokenConfig:
    method __init__ (line 67) | def __init__(self, data: dict):
    method set_token_list (line 73) | def set_token_list(self, data):
    method get_token_list (line 81) | def get_token_list(self) -> List[Token]:
    method __repr__ (line 84) | def __repr__(self):

FILE: pymaker/numeric.py
  class Wad (line 28) | class Wad:
    method __init__ (line 42) | def __init__(self, value):
    method from_number (line 63) | def from_number(cls, number):
    method __repr__ (line 69) | def __repr__(self):
    method __str__ (line 72) | def __str__(self):
    method __add__ (line 76) | def __add__(self, other):
    method __sub__ (line 82) | def __sub__(self, other):
    method __mod__ (line 88) | def __mod__(self, other):
    method __mul__ (line 95) | def __mul__(self, other):
    method __truediv__ (line 110) | def __truediv__(self, other):
    method __abs__ (line 116) | def __abs__(self):
    method __eq__ (line 119) | def __eq__(self, other):
    method __hash__ (line 125) | def __hash__(self):
    method __lt__ (line 128) | def __lt__(self, other):
    method __int__ (line 134) | def __int__(self):
    method __float__ (line 137) | def __float__(self):
    method __round__ (line 140) | def __round__(self, ndigits: int = 0):
    method __sqrt__ (line 143) | def __sqrt__(self):
    method min (line 147) | def min(*args):
    method max (line 152) | def max(*args):
  class Ray (line 158) | class Ray:
    method __init__ (line 172) | def __init__(self, value):
    method from_number (line 193) | def from_number(cls, number):
    method __repr__ (line 199) | def __repr__(self):
    method __str__ (line 202) | def __str__(self):
    method __add__ (line 206) | def __add__(self, other):
    method __sub__ (line 212) | def __sub__(self, other):
    method __mod__ (line 218) | def __mod__(self, other):
    method __mul__ (line 224) | def __mul__(self, other):
    method __truediv__ (line 239) | def __truediv__(self, other):
    method __abs__ (line 245) | def __abs__(self):
    method __eq__ (line 248) | def __eq__(self, other):
    method __hash__ (line 254) | def __hash__(self):
    method __lt__ (line 257) | def __lt__(self, other):
    method __int__ (line 263) | def __int__(self):
    method __float__ (line 266) | def __float__(self):
    method __round__ (line 269) | def __round__(self, ndigits: int = 0):
    method __sqrt__ (line 272) | def __sqrt__(self):
    method min (line 276) | def min(*args):
    method max (line 281) | def max(*args):
  class Rad (line 287) | class Rad:
    method __init__ (line 301) | def __init__(self, value):
    method from_number (line 322) | def from_number(cls, number):
    method __repr__ (line 328) | def __repr__(self):
    method __str__ (line 331) | def __str__(self):
    method __add__ (line 335) | def __add__(self, other):
    method __sub__ (line 341) | def __sub__(self, other):
    method __mod__ (line 347) | def __mod__(self, other):
    method __mul__ (line 353) | def __mul__(self, other):
    method __truediv__ (line 368) | def __truediv__(self, other):
    method __abs__ (line 374) | def __abs__(self):
    method __eq__ (line 377) | def __eq__(self, other):
    method __hash__ (line 383) | def __hash__(self):
    method __lt__ (line 386) | def __lt__(self, other):
    method __int__ (line 392) | def __int__(self):
    method __float__ (line 395) | def __float__(self):
    method __round__ (line 398) | def __round__(self, ndigits: int = 0):
    method __sqrt__ (line 401) | def __sqrt__(self):
    method min (line 405) | def min(*args):
    method max (line 410) | def max(*args):

FILE: pymaker/oasis.py
  class Order (line 34) | class Order:
    method __init__ (line 50) | def __init__(self, market, order_id: int, maker: Address, pay_token: A...
    method sell_to_buy_price (line 70) | def sell_to_buy_price(self) -> Wad:
    method buy_to_sell_price (line 74) | def buy_to_sell_price(self) -> Wad:
    method remaining_buy_amount (line 78) | def remaining_buy_amount(self) -> Wad:
    method remaining_sell_amount (line 82) | def remaining_sell_amount(self) -> Wad:
    method __eq__ (line 85) | def __eq__(self, other):
    method __hash__ (line 89) | def __hash__(self):
    method __repr__ (line 92) | def __repr__(self):
  class LogMake (line 96) | class LogMake:
    method __init__ (line 97) | def __init__(self, log):
    method from_receipt (line 108) | def from_receipt(cls, receipt: Receipt):
    method __repr__ (line 120) | def __repr__(self):
  class LogBump (line 124) | class LogBump:
    method __init__ (line 125) | def __init__(self, log):
    method __repr__ (line 135) | def __repr__(self):
  class LogTake (line 139) | class LogTake:
    method __init__ (line 140) | def __init__(self, log):
    method from_event (line 152) | def from_event(cls, event: dict):
    method __eq__ (line 163) | def __eq__(self, other):
    method __repr__ (line 167) | def __repr__(self):
  class LogKill (line 171) | class LogKill:
    method __init__ (line 172) | def __init__(self, log):
    method __repr__ (line 182) | def __repr__(self):
  class SimpleMarket (line 186) | class SimpleMarket(Contract):
    method __init__ (line 203) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 212) | def deploy(web3: Web3):
    method approve (line 223) | def approve(self, tokens: List[ERC20Token], approval_function):
    method past_make (line 239) | def past_make(self, number_of_past_blocks: int, event_filter: dict = N...
    method past_bump (line 256) | def past_bump(self, number_of_past_blocks: int, event_filter: dict = N...
    method past_take (line 273) | def past_take(self, number_of_past_blocks: int, event_filter: dict = N...
    method past_kill (line 290) | def past_kill(self, number_of_past_blocks: int, event_filter: dict = N...
    method get_last_order_id (line 307) | def get_last_order_id(self) -> int:
    method get_order (line 315) | def get_order(self, order_id: int, block_ident: Optional[str] = None) ...
    method get_orders (line 340) | def get_orders(self, pay_token: Address = None, buy_token: Address = N...
    method get_orders_by_maker (line 364) | def get_orders_by_maker(self, maker: Address) -> List[Order]:
    method make (line 392) | def make(self, pay_token: Address, pay_amount: Wad, buy_token: Address...
    method bump (line 420) | def bump(self, order_id: int) -> Transact:
    method take (line 437) | def take(self, order_id: int, quantity: Wad) -> Transact:
    method kill (line 457) | def kill(self, order_id: int) -> Transact:
    method _make_order_id_result_function (line 473) | def _make_order_id_result_function(receipt):
    method __repr__ (line 476) | def __repr__(self):
  class MatchingMarket (line 480) | class MatchingMarket(SimpleMarket):
    method __init__ (line 497) | def __init__(self, web3: Web3, address: Address, support_address: Opti...
    method deploy (line 507) | def deploy(web3: Web3, dust_token: Address, dust_limit: Wad, price_ora...
    method add_token_pair_whitelist (line 532) | def add_token_pair_whitelist(self, base_token: Address, quote_token: A...
    method get_orders (line 550) | def get_orders(self, p_token: Token = None,  b_token: Token = None, bl...
    method make (line 627) | def make(self, p_token: Token, pay_amount: Wad, b_token: Token, buy_am...
    method position (line 681) | def position(self, p_token: Token, pay_amount: Wad, b_token: Token, bu...
    method __repr__ (line 723) | def __repr__(self):

FILE: pymaker/oracles.py
  class OSM (line 25) | class OSM(Contract):
    method __init__ (line 39) | def __init__(self, web3: Web3, address: Address):
    method poke (line 47) | def poke(self) -> Transact:
    method peek (line 50) | def peek(self) -> Wad:
    method peep (line 53) | def peep(self) -> Wad:
    method zzz (line 56) | def zzz(self) -> int:
    method _extract_price (line 59) | def _extract_price(self, storage_slot: int) -> int:
    method __repr__ (line 63) | def __repr__(self):
  class OldUniv2LpOSM (line 67) | class OldUniv2LpOSM(OSM):
    method __init__ (line 74) | def __init__(self, web3: Web3, address: Address):
    method peek (line 77) | def peek(self) -> Wad:
    method peep (line 80) | def peep(self) -> Wad:

FILE: pymaker/proxy.py
  class DSProxyCache (line 30) | class DSProxyCache(Contract):
    method __init__ (line 39) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 48) | def deploy(cls, web3: Web3):
    method read (line 51) | def read(self, code: str) -> Optional[Address]:
    method write (line 65) | def write(self, code: str):
    method __repr__ (line 75) | def __repr__(self):
  class DSProxy (line 79) | class DSProxy(Contract):
    method __init__ (line 88) | def __init__(self, web3: Web3, address: Address):
    method authority (line 96) | def authority(self) -> Address:
    method set_authority (line 104) | def set_authority(self, address: Address) -> Transact:
    method deploy (line 117) | def deploy(cls, web3: Web3, cache: Address):
    method execute (line 120) | def execute(self, code: str, calldata: Calldata) -> Transact:
    method call (line 132) | def call(self, code: str, calldata: Calldata) -> (Address, HexBytes):
    method execute_at (line 141) | def execute_at(self, address: Address, calldata: Calldata) -> Transact:
    method call_at (line 148) | def call_at(self, address: Address, calldata: Calldata) -> Transact:
    method set_cache (line 157) | def set_cache(self, address: Address) -> Transact:
    method cache (line 162) | def cache(self) -> Address:
    method __repr__ (line 165) | def __repr__(self):
  class LogCreated (line 170) | class LogCreated:
    method __init__ (line 171) | def __init__(self, log):
    method from_event (line 179) | def from_event(cls, event: dict):
    method __eq__ (line 192) | def __eq__(self, other):
  class DSProxyFactory (line 197) | class DSProxyFactory(Contract):
    method __init__ (line 206) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 215) | def deploy(cls, web3: Web3):
    method build (line 218) | def build(self) -> Transact:
    method build_for (line 221) | def build_for(self, address: Address) -> Transact:
    method cache (line 226) | def cache(self) -> Address:
    method is_proxy (line 229) | def is_proxy(self, address: Address) -> bool:
    method past_build (line 234) | def past_build(self, number_of_past_blocks: int, event_filter: dict = ...
    method log_created (line 252) | def log_created(cls, receipt: Receipt) -> List[LogCreated]:
    method __repr__ (line 264) | def __repr__(self):
  class ProxyRegistry (line 268) | class ProxyRegistry(Contract):
    method __init__ (line 277) | def __init__(self, web3: Web3, address: Address):
    method build (line 285) | def build(self, owner: Address) -> Transact:
    method proxies (line 289) | def proxies(self, owner: Address) -> Address:
    method __repr__ (line 293) | def __repr__(self):
  class DssProxyActionsDsr (line 297) | class DssProxyActionsDsr(Contract):
    method __init__ (line 306) | def __init__(self, web3: Web3, address: Address):

FILE: pymaker/reloadable_config.py
  class ReloadableConfig (line 19) | class ReloadableConfig:
    method __init__ (line 32) | def __init__(self, filename: str):
    method _import_callback (line 42) | def _import_callback(self, paths: list):
    method _load_mtimes (line 53) | def _load_mtimes(self, imported_paths: List[str]) -> dict:
    method _mtimes_changed (line 56) | def _mtimes_changed(self, imported_paths_to_mtimes: dict) -> bool:
    method get_config (line 63) | def get_config(self):

FILE: pymaker/sai.py
  class Cup (line 28) | class Cup:
    method __init__ (line 41) | def __init__(self, cup_id: int, lad: Address, ink: Wad, art: Wad):
    method __repr__ (line 51) | def __repr__(self):
  class Tub (line 55) | class Tub(Contract):
    method __init__ (line 76) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 85) | def deploy(web3: Web3, sai: Address, sin: Address, skr: Address, gem: ...
    method set_authority (line 100) | def set_authority(self, address: Address) -> Transact:
    method approve (line 104) | def approve(self, approval_function):
    method era (line 120) | def era(self) -> int:
    method tap (line 128) | def tap(self) -> Address:
    method sai (line 136) | def sai(self) -> Address:
    method sin (line 144) | def sin(self) -> Address:
    method gov (line 152) | def gov(self) -> Address:
    method vox (line 160) | def vox(self) -> Address:
    method pit (line 168) | def pit(self) -> Address:
    method skr (line 176) | def skr(self) -> Address:
    method gem (line 184) | def gem(self) -> Address:
    method pip (line 192) | def pip(self) -> Address:
    method pep (line 200) | def pep(self) -> Address:
    method axe (line 208) | def axe(self) -> Ray:
    method cap (line 216) | def cap(self) -> Wad:
    method mat (line 224) | def mat(self) -> Ray:
    method tax (line 232) | def tax(self) -> Ray:
    method reg (line 240) | def reg(self) -> int:
    method fit (line 248) | def fit(self) -> Ray:
    method rho (line 256) | def rho(self) -> int:
    method tau (line 264) | def tau(self) -> int:
    method chi (line 272) | def chi(self) -> Ray:
    method mold_axe (line 284) | def mold_axe(self, new_axe: Ray) -> Transact:
    method mold_cap (line 296) | def mold_cap(self, new_cap: Wad) -> Transact:
    method mold_mat (line 308) | def mold_mat(self, new_mat: Ray) -> Transact:
    method mold_tax (line 320) | def mold_tax(self, new_tax: Ray) -> Transact:
    method mold_gap (line 332) | def mold_gap(self, new_gap: Wad) -> Transact:
    method drip (line 344) | def drip(self) -> Transact:
    method prod (line 352) | def prod(self) -> Transact:
    method din (line 360) | def din(self) -> Wad:
    method pie (line 368) | def pie(self) -> Wad:
    method air (line 376) | def air(self) -> Wad:
    method tag (line 384) | def tag(self) -> Ray:
    method per (line 395) | def per(self) -> Ray:
    method gap (line 406) | def gap(self) -> Wad:
    method bid (line 414) | def bid(self, amount: Wad) -> Wad:
    method ask (line 424) | def ask(self, amount: Wad) -> Wad:
    method cupi (line 434) | def cupi(self) -> int:
    method cups (line 442) | def cups(self, cup_id: int) -> Cup:
    method tab (line 455) | def tab(self, cup_id: int) -> Wad:
    method ink (line 467) | def ink(self, cup_id: int) -> Wad:
    method lad (line 479) | def lad(self, cup_id: int) -> Address:
    method safe (line 491) | def safe(self, cup_id: int) -> bool:
    method join (line 503) | def join(self, amount_in_skr: Wad) -> Transact:
    method exit (line 515) | def exit(self, amount_in_skr: Wad) -> Transact:
    method open (line 528) | def open(self) -> Transact:
    method shut (line 536) | def shut(self, cup_id: int) -> Transact:
    method lock (line 551) | def lock(self, cup_id: int, amount_in_skr: Wad) -> Transact:
    method free (line 566) | def free(self, cup_id: int, amount_in_skr: Wad) -> Transact:
    method draw (line 581) | def draw(self, cup_id: int, amount_in_sai: Wad) -> Transact:
    method wipe (line 596) | def wipe(self, cup_id: int, amount_in_sai: Wad) -> Transact:
    method give (line 611) | def give(self, cup_id: int, new_lad: Address) -> Transact:
    method bite (line 626) | def bite(self, cup_id: int) -> Transact:
    method __eq__ (line 638) | def __eq__(self, other):
    method __repr__ (line 642) | def __repr__(self):
  class Tap (line 646) | class Tap(Contract):
    method __init__ (line 657) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 666) | def deploy(web3: Web3, tub: Address):
    method set_authority (line 670) | def set_authority(self, address: Address) -> Transact:
    method approve (line 674) | def approve(self, approval_function):
    method tub (line 691) | def tub(self) -> Address:
    method sai (line 699) | def sai(self) -> Address:
    method sin (line 707) | def sin(self) -> Address:
    method skr (line 715) | def skr(self) -> Address:
    method woe (line 723) | def woe(self) -> Wad:
    method fog (line 731) | def fog(self) -> Wad:
    method joy (line 740) | def joy(self) -> Wad:
    method gap (line 750) | def gap(self) -> Wad:
    method mold_gap (line 758) | def mold_gap(self, new_gap: Wad) -> Transact:
    method s2s (line 770) | def s2s(self) -> Ray:
    method bid (line 778) | def bid(self, amount_in_skr: Wad) -> Wad:
    method ask (line 787) | def ask(self, amount_in_skr: Wad) -> Wad:
    method boom (line 796) | def boom(self, amount_in_skr: Wad) -> Transact:
    method bust (line 808) | def bust(self, amount_in_skr: Wad) -> Transact:
    method cash (line 820) | def cash(self, amount_in_sai: Wad) -> Transact:
    method mock (line 831) | def mock(self, amount_in_sai: Wad) -> Transact:
    method __eq__ (line 842) | def __eq__(self, other):
    method __repr__ (line 846) | def __repr__(self):
  class Top (line 850) | class Top(Contract):
    method __init__ (line 861) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 870) | def deploy(web3: Web3, tub: Address, tap: Address):
    method set_authority (line 875) | def set_authority(self, address: Address) -> Transact:
    method fix (line 879) | def fix(self) -> Ray:
    method cage (line 887) | def cage(self) -> Transact:
    method __eq__ (line 897) | def __eq__(self, other):
    method __repr__ (line 901) | def __repr__(self):
  class Vox (line 905) | class Vox(Contract):
    method __init__ (line 916) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 925) | def deploy(web3: Web3, per: Ray):
    method set_authority (line 929) | def set_authority(self, address: Address) -> Transact:
    method era (line 933) | def era(self) -> int:
    method par (line 941) | def par(self) -> Ray:
    method __eq__ (line 953) | def __eq__(self, other):
    method __repr__ (line 957) | def __repr__(self):

FILE: pymaker/shutdown.py
  class ShutdownModule (line 34) | class ShutdownModule(Contract):
    method __init__ (line 46) | def __init__(self, web3: Web3, address: Address):
    method sum (line 54) | def sum(self) -> Wad:
    method sum_of (line 58) | def sum_of(self, address: Address) -> Wad:
    method min (line 64) | def min(self) -> Wad:
    method join (line 68) | def join(self, value: Wad) -> Transact:
    method fire (line 73) | def fire(self):
    method deny (line 78) | def deny(self, address: Address):
    method burn (line 82) | def burn(self):
  class End (line 87) | class End(Contract):
    method __init__ (line 99) | def __init__(self, web3: Web3, address: Address):
    method live (line 107) | def live(self) -> bool:
    method when (line 111) | def when(self) -> datetime:
    method wait (line 116) | def wait(self) -> int:
    method debt (line 120) | def debt(self) -> Rad:
    method tag (line 124) | def tag(self, ilk: Ilk) -> Ray:
    method gap (line 129) | def gap(self, ilk: Ilk) -> Wad:
    method art (line 134) | def art(self, ilk: Ilk) -> Wad:
    method fix (line 139) | def fix(self, ilk: Ilk) -> Ray:
    method bag (line 144) | def bag(self, address: Address) -> Wad:
    method out (line 149) | def out(self, ilk: Ilk, address: Address) -> Wad:
    method cage (line 154) | def cage(self, ilk: Ilk) -> Transact:
    method snip (line 159) | def snip(self, ilk: Ilk, clip_id: int) -> Transact:
    method skip (line 165) | def skip(self, ilk: Ilk, flip_id: int) -> Transact:
    method skim (line 171) | def skim(self, ilk: Ilk, address: Address) -> Transact:
    method free (line 178) | def free(self, ilk: Ilk) -> Transact:
    method thaw (line 183) | def thaw(self):
    method flow (line 187) | def flow(self, ilk: Ilk) -> Transact:
    method pack (line 192) | def pack(self, dai: Wad) -> Transact:
    method cash (line 197) | def cash(self, ilk: Ilk, dai: Wad):

FILE: pymaker/sign.py
  function eth_sign (line 31) | def eth_sign(message: bytes, web3: Web3, key=None, in_hexbytes=False, ac...
  function to_vrs (line 75) | def to_vrs(signature: str) -> Tuple[int, bytes, bytes]:

FILE: pymaker/tightly_packed.py
  function encode_address (line 23) | def encode_address(address: Address) -> bytes:
  function encode_uint256 (line 27) | def encode_uint256(value: int) -> bytes:
  function encode_bytes (line 31) | def encode_bytes(value: bytes) -> bytes:

FILE: pymaker/token.py
  class ERC20Token (line 26) | class ERC20Token(Contract):
    method __init__ (line 37) | def __init__(self, web3: Web3, address: Address):
    method name (line 45) | def name(self) -> str:
    method symbol (line 57) | def symbol(self) -> str:
    method total_supply (line 69) | def total_supply(self) -> Wad:
    method balance_of (line 77) | def balance_of(self, address: Address) -> Wad:
    method balance_at_block (line 90) | def balance_at_block(self, address: Address, block_identifier: int = '...
    method allowance_of (line 105) | def allowance_of(self, address: Address, payee: Address) -> Wad:
    method transfer (line 123) | def transfer(self, address: Address, value: Wad) -> Transact:
    method transfer_from (line 138) | def transfer_from(self, source_address: Address, destination_address: ...
    method approve (line 157) | def approve(self, payee: Address, limit: Wad = Wad(2**256 - 1)) -> Tra...
    method __eq__ (line 179) | def __eq__(self, other):
    method __repr__ (line 182) | def __repr__(self):
  class DSToken (line 186) | class DSToken(ERC20Token):
    method deploy (line 201) | def deploy(web3: Web3, symbol: str):
    method authority (line 214) | def authority(self) -> Address:
    method set_authority (line 222) | def set_authority(self, address: Address) -> Transact:
    method mint (line 234) | def mint(self, amount: Wad) -> Transact:
    method mint_to (line 246) | def mint_to(self, address: Address, amount: Wad) -> Transact:
    method burn (line 261) | def burn(self, amount: Wad) -> Transact:
    method burn_from (line 273) | def burn_from(self, address: Address, amount: Wad) -> Transact:
    method __repr__ (line 287) | def __repr__(self):
  class DSEthToken (line 291) | class DSEthToken(ERC20Token):
    method deploy (line 310) | def deploy(web3: Web3):
    method __init__ (line 321) | def __init__(self, web3, address):
    method deposit (line 325) | def deposit(self, amount: Wad) -> Transact:
    method withdraw (line 337) | def withdraw(self, amount: Wad) -> Transact:
    method __repr__ (line 351) | def __repr__(self):
  class EthToken (line 355) | class EthToken():
    method __init__ (line 363) | def __init__(self, web3: Web3, address: Address):
    method balance_of (line 370) | def balance_of(self, address):

FILE: pymaker/transactional.py
  class TxManager (line 28) | class TxManager(Contract):
    method __init__ (line 52) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 61) | def deploy(web3: Web3):
    method approve (line 64) | def approve(self, tokens: List[ERC20Token], approval_function):
    method owner (line 80) | def owner(self) -> Address:
    method execute (line 83) | def execute(self, tokens: List[Address], invocations: List[Invocation]...
    method __repr__ (line 110) | def __repr__(self):

FILE: pymaker/util.py
  function chain (line 27) | def chain(web3: Web3) -> str:
  function http_response_summary (line 41) | def http_response_summary(response) -> str:
  function synchronize (line 47) | def synchronize(futures) -> list:
  function eth_balance (line 58) | def eth_balance(web3: Web3, address) -> Wad:
  function is_contract_at (line 62) | def is_contract_at(web3: Web3, address):
  function int_to_bytes32 (line 67) | def int_to_bytes32(value: int) -> bytes:
  function bytes_to_int (line 72) | def bytes_to_int(value) -> int:
  function bytes_to_hexstring (line 83) | def bytes_to_hexstring(value) -> str:
  function hexstring_to_bytes (line 94) | def hexstring_to_bytes(value: str) -> bytes:
  class AsyncCallback (line 100) | class AsyncCallback:
    method __init__ (line 116) | def __init__(self, callback):
    method trigger (line 120) | def trigger(self, on_start=None, on_finish=None) -> bool:
    method wait (line 156) | def wait(self):

FILE: pymaker/vault.py
  class DSVault (line 23) | class DSVault(Contract):
    method __init__ (line 37) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 46) | def deploy(web3: Web3):
    method authority (line 57) | def authority(self) -> Address:
    method set_authority (line 65) | def set_authority(self, address: Address) -> Transact:
    method __repr__ (line 77) | def __repr__(self):

FILE: pymaker/zrx.py
  class Order (line 40) | class Order:
    method __init__ (line 41) | def __init__(self, exchange, maker: Address, taker: Address, maker_fee...
    method order_id (line 80) | def order_id(self):
    method sell_to_buy_price (line 84) | def sell_to_buy_price(self) -> Wad:
    method buy_to_sell_price (line 88) | def buy_to_sell_price(self) -> Wad:
    method remaining_buy_amount (line 92) | def remaining_buy_amount(self) -> Wad:
    method remaining_sell_amount (line 96) | def remaining_sell_amount(self) -> Wad:
    method from_json (line 106) | def from_json(exchange, data: dict):
    method to_json_without_fees (line 126) | def to_json_without_fees(self) -> dict:
    method to_json (line 139) | def to_json(self) -> dict:
    method __eq__ (line 160) | def __eq__(self, other):
    method __hash__ (line 178) | def __hash__(self):
    method __str__ (line 195) | def __str__(self):
    method __repr__ (line 200) | def __repr__(self):
  class LogCancel (line 204) | class LogCancel:
    method __init__ (line 205) | def __init__(self, log):
    method __repr__ (line 216) | def __repr__(self):
  class LogFill (line 220) | class LogFill:
    method __init__ (line 221) | def __init__(self, log):
    method from_event (line 236) | def from_event(cls, event: dict):
    method __eq__ (line 246) | def __eq__(self, other):
    method __repr__ (line 250) | def __repr__(self):
  class ZrxExchange (line 254) | class ZrxExchange(Contract):
    method deploy (line 271) | def deploy(web3: Web3, zrx_token: Address, token_transfer_proxy: Addre...
    method __init__ (line 288) | def __init__(self, web3: Web3, address: Address):
    method zrx_token (line 296) | def zrx_token(self) -> Address:
    method token_transfer_proxy (line 304) | def token_transfer_proxy(self) -> Address:
    method approve (line 312) | def approve(self, tokens: List[ERC20Token], approval_function):
    method past_fill (line 333) | def past_fill(self, number_of_past_blocks: int, event_filter: dict = N...
    method past_cancel (line 350) | def past_cancel(self, number_of_past_blocks: int, event_filter: dict =...
    method create_order (line 367) | def create_order(self,
    method get_order_hash (line 412) | def get_order_hash(self, order: Order) -> str:
    method get_unavailable_buy_amount (line 429) | def get_unavailable_buy_amount(self, order: Order) -> Wad:
    method sign_order (line 444) | def sign_order(self, order: Order) -> Order:
    method fill_order (line 467) | def fill_order(self, order: Order, fill_buy_amount: Wad) -> Transact:
    method cancel_order (line 486) | def cancel_order(self, order: Order) -> Transact:
    method _order_values (line 501) | def _order_values(order):
    method _order_addresses (line 510) | def _order_addresses(order):
    method generate_salt (line 518) | def generate_salt() -> int:
    method __repr__ (line 521) | def __repr__(self):
  class ZrxRelayerApi (line 525) | class ZrxRelayerApi:
    method __init__ (line 537) | def __init__(self, exchange: ZrxExchange, api_server: str):
    method get_orders (line 544) | def get_orders(self, pay_token: Address, buy_token: Address, per_page:...
    method get_orders_by_maker (line 572) | def get_orders_by_maker(self, maker: Address, per_page: int = 100) -> ...
    method calculate_fees (line 599) | def calculate_fees(self, order: Order) -> Order:
    method submit_order (line 633) | def submit_order(self, order: Order) -> bool:
    method __repr__ (line 654) | def __repr__(self):

FILE: pymaker/zrxv2.py
  class Asset (line 42) | class Asset:
    method deserialize (line 44) | def deserialize(asset: str):
    method serialize (line 53) | def serialize(self) -> str:
    method __repr__ (line 56) | def __repr__(self):
  class ERC20Asset (line 60) | class ERC20Asset(Asset):
    method __init__ (line 63) | def __init__(self, token_address: Address):
    method serialize (line 68) | def serialize(self) -> str:
    method __hash__ (line 71) | def __hash__(self):
    method __eq__ (line 74) | def __eq__(self, other):
  class UnknownAsset (line 78) | class UnknownAsset(Asset):
    method __init__ (line 79) | def __init__(self, asset: str):
    method serialize (line 84) | def serialize(self) -> str:
    method __hash__ (line 87) | def __hash__(self):
    method __eq__ (line 90) | def __eq__(self, other):
  class Order (line 94) | class Order:
    method __init__ (line 95) | def __init__(self, exchange, sender: Address, maker: Address, taker: A...
    method order_id (line 132) | def order_id(self):
    method sell_to_buy_price (line 136) | def sell_to_buy_price(self) -> Wad:
    method buy_to_sell_price (line 140) | def buy_to_sell_price(self) -> Wad:
    method remaining_buy_amount (line 144) | def remaining_buy_amount(self) -> Wad:
    method remaining_sell_amount (line 148) | def remaining_sell_amount(self) -> Wad:
    method from_json (line 158) | def from_json(exchange, data: dict):
    method to_json_without_fees (line 177) | def to_json_without_fees(self) -> dict:
    method to_json (line 189) | def to_json(self) -> dict:
    method __eq__ (line 207) | def __eq__(self, other):
    method __hash__ (line 224) | def __hash__(self):
    method __str__ (line 240) | def __str__(self):
    method __repr__ (line 245) | def __repr__(self):
  class LogCancel (line 249) | class LogCancel:
    method __init__ (line 250) | def __init__(self, log):
    method __repr__ (line 259) | def __repr__(self):
  class LogFill (line 263) | class LogFill:
    method __init__ (line 264) | def __init__(self, log):
    method from_event (line 279) | def from_event(cls, event: dict):
    method __eq__ (line 293) | def __eq__(self, other):
    method __repr__ (line 297) | def __repr__(self):
  class ZrxExchangeV2 (line 301) | class ZrxExchangeV2(Contract):
    method deploy (line 320) | def deploy(web3: Web3, zrx_asset: str):
    method __init__ (line 333) | def __init__(self, web3: Web3, address: Address):
    method zrx_asset (line 341) | def zrx_asset(self) -> str:
    method zrx_token (line 349) | def zrx_token(self) -> Address:
    method asset_transfer_proxy (line 357) | def asset_transfer_proxy(self, proxy_id: str) -> Address:
    method approve (line 367) | def approve(self, tokens: List[ERC20Token], approval_function):
    method past_fill (line 388) | def past_fill(self, number_of_past_blocks: int, event_filter: dict = N...
    method past_cancel (line 405) | def past_cancel(self, number_of_past_blocks: int, event_filter: dict =...
    method create_order (line 422) | def create_order(self,
    method _get_order_info (line 466) | def _get_order_info(self, order):
    method get_order_hash (line 478) | def get_order_hash(self, order: Order) -> str:
    method get_unavailable_buy_amount (line 494) | def get_unavailable_buy_amount(self, order: Order) -> Wad:
    method sign_order (line 519) | def sign_order(self, order: Order) -> Order:
    method fill_order (line 542) | def fill_order(self, order: Order, fill_buy_amount: Wad) -> Transact:
    method cancel_order (line 565) | def cancel_order(self, order: Order) -> Transact:
    method _order_tuple (line 585) | def _order_tuple(order):
    method generate_salt (line 600) | def generate_salt() -> int:
    method __repr__ (line 603) | def __repr__(self):
  class ZrxRelayerApiV2 (line 607) | class ZrxRelayerApiV2:
    method __init__ (line 619) | def __init__(self, exchange: ZrxExchangeV2, api_server: str):
    method get_book (line 626) | def get_book(self, pay_token: Address, buy_token: Address, depth: int ...
    method get_orders (line 644) | def get_orders(self, pay_token: Address, buy_token: Address, per_page:...
    method get_order (line 676) | def get_order(self, order_hash: str) -> Order:
    method get_orders_by_maker (line 685) | def get_orders_by_maker(self, maker: Address, per_page: int = 100) -> ...
    method configure_order (line 716) | def configure_order(self, order: Order) -> Order:
    method submit_order (line 753) | def submit_order(self, order: Order) -> bool:
    method __repr__ (line 774) | def __repr__(self):

FILE: tests/conftest.py
  function new_deployment (line 31) | def new_deployment() -> Deployment:
  function deployment (line 36) | def deployment(new_deployment: Deployment) -> Deployment:
  function web3 (line 42) | def web3() -> Web3:
  function our_address (line 63) | def our_address(web3) -> Address:
  function other_address (line 68) | def other_address(web3) -> Address:
  function deployment_address (line 73) | def deployment_address(web3) -> Address:
  function mcd (line 79) | def mcd(web3) -> DssDeployment:
  function validate_contracts_loaded (line 87) | def validate_contracts_loaded(deployment: DssDeployment):
  function initialize_collaterals (line 106) | def initialize_collaterals(deployment: DssDeployment):

FILE: tests/dss_token.py
  class GemMock (line 24) | class GemMock(Contract):
    method __init__ (line 31) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 40) | def deploy(web3: Web3, vat: Address, ilk: Ilk, gem: Address):
    method ilk (line 49) | def ilk(self):
    method join (line 52) | def join(self, urn: Urn, value: Wad) -> Transact:
    method hope (line 59) | def hope(self, guy: Address) -> Transact:
    method __eq__ (line 65) | def __eq__(self, other):
    method __repr__ (line 68) | def __repr__(self):

FILE: tests/helpers.py
  function is_hashable (line 24) | def is_hashable(v):
  function wait_until_mock_called (line 33) | def wait_until_mock_called(mock: Mock):
  function time_travel_by (line 39) | def time_travel_by(web3: Web3, seconds: int):
  function snapshot (line 54) | def snapshot(web3: Web3):
  function reset (line 60) | def reset(web3: Web3, snap_id):

FILE: tests/manual_test_async_tx.py
  class TestApp (line 52) | class TestApp:
    method main (line 53) | def main(self):
    method test_replacement (line 58) | def test_replacement(self):
    method test_simultaneous (line 70) | def test_simultaneous(self):
    method shutdown (line 77) | def shutdown(self):
    method _run_future (line 87) | def _run_future(future):

FILE: tests/manual_test_goerli.py
  class TestApp (line 70) | class TestApp:
    method main (line 71) | def main(self):
    method on_block (line 75) | def on_block(self):

FILE: tests/manual_test_node.py
  class TestApp (line 58) | class TestApp:
    method __init__ (line 59) | def __init__(self):
    method main (line 63) | def main(self):
    method on_block (line 68) | def on_block(self):
    method request_history (line 80) | def request_history(self):
    method on_shutdown (line 84) | def on_shutdown(self):

FILE: tests/manual_test_tx_recovery.py
  class TestApp (line 49) | class TestApp:
    method main (line 50) | def main(self):
    method startup (line 70) | def startup(self):
    method shutdown (line 73) | def shutdown(self):
    method _run_future (line 77) | def _run_future(future):

FILE: tests/test_approval.py
  class FailingTransact (line 33) | class FailingTransact:
    method transact (line 34) | def transact(self):
    method transact_async (line 37) | async def transact_async(self):
  function setup_module (line 41) | def setup_module():
  function setup_function (line 50) | def setup_function():
  function test_direct_approval (line 55) | def test_direct_approval():
  function test_direct_approval_should_obey_from_address (line 66) | def test_direct_approval_should_obey_from_address():
  function test_direct_approval_should_obey_gas_price (line 81) | def test_direct_approval_should_obey_gas_price():
  function test_direct_approval_should_not_approve_if_already_approved (line 92) | def test_direct_approval_should_not_approve_if_already_approved():
  function test_direct_approval_should_raise_exception_if_approval_fails (line 104) | def test_direct_approval_should_raise_exception_if_approval_fails():
  function test_via_tx_manager_approval (line 114) | def test_via_tx_manager_approval():
  function test_via_tx_manager_approval_should_obey_gas_price (line 126) | def test_via_tx_manager_approval_should_obey_gas_price():
  function test_via_tx_manager_approval_should_not_approve_if_already_approved (line 138) | def test_via_tx_manager_approval_should_not_approve_if_already_approved():
  function test_via_tx_manager_approval_should_raise_exception_if_approval_fails (line 151) | def test_via_tx_manager_approval_should_raise_exception_if_approval_fail...

FILE: tests/test_auctions.py
  function create_surplus (line 32) | def create_surplus(mcd: DssDeployment, flapper: Flapper, deployment_addr...
  function create_debt (line 56) | def create_debt(web3: Web3, mcd: DssDeployment, our_address: Address, de...
  function check_active_auctions (line 123) | def check_active_auctions(auction: DealableAuctionContract):
  class TestFlapper (line 131) | class TestFlapper:
    method flapper (line 133) | def flapper(self, mcd: DssDeployment) -> Flapper:
    method tend (line 137) | def tend(flapper: Flapper, id: int, address: Address, lot: Rad, bid: W...
    method last_log (line 163) | def last_log(flapper: Flapper):
    method test_getters (line 167) | def test_getters(self, mcd, flapper):
    method test_scenario (line 174) | def test_scenario(self, web3, mcd, flapper, our_address, other_address...
  class TestFlipper (line 228) | class TestFlipper:
    method collateral (line 230) | def collateral(self, mcd: DssDeployment) -> Collateral:
    method flipper (line 234) | def flipper(self, collateral, deployment_address) -> Flipper:
    method tend (line 238) | def tend(flipper: Flipper, id: int, address: Address, lot: Wad, bid: R...
    method dent (line 257) | def dent(flipper: Flipper, id: int, address: Address, lot: Wad, bid: R...
    method last_log (line 276) | def last_log(flipper: Flipper):
    method test_getters (line 280) | def test_getters(self, mcd, flipper):
    method test_scenario (line 287) | def test_scenario(self, web3, mcd, collateral, flipper, our_address, o...
  class TestClipper (line 429) | class TestClipper:
    method collateral (line 431) | def collateral(self, mcd: DssDeployment) -> Collateral:
    method clipper (line 435) | def clipper(self, collateral, deployment_address) -> Clipper:
    method last_log (line 439) | def last_log(clipper: Clipper):
    method test_getters (line 443) | def test_getters(self, mcd, clipper):
    method test_scenario (line 459) | def test_scenario(self, web3, mcd, collateral, clipper, our_address, o...
  class TestFlopper (line 623) | class TestFlopper:
    method flopper (line 625) | def flopper(self, mcd: DssDeployment) -> Flopper:
    method dent (line 629) | def dent(flopper: Flopper, id: int, address: Address, lot: Wad, bid: R...
    method last_log (line 655) | def last_log(flopper: Flopper):
    method test_getters (line 659) | def test_getters(self, mcd, flopper):
    method test_scenario (line 667) | def test_scenario(self, web3, mcd, flopper, our_address, other_address...

FILE: tests/test_auth.py
  class TestDSGuard (line 26) | class TestDSGuard:
    method setup_method (line 27) | def setup_method(self):
    method can_call (line 33) | def can_call(self, src: str, dst: str, sig: str) -> bool:
    method test_fail_when_no_contract_under_that_address (line 36) | def test_fail_when_no_contract_under_that_address(self):
    method test_no_permit_by_default (line 41) | def test_no_permit_by_default(self):
    method test_permit_any_to_any_with_any_sig (line 47) | def test_permit_any_to_any_with_any_sig(self):
    method test_permit_specific_addresses_and_sig (line 56) | def test_permit_specific_addresses_and_sig(self):
  class TestDSAuth (line 76) | class TestDSAuth:
    method setup_method (line 77) | def setup_method(self):
    method test_owner (line 85) | def test_owner(self):

FILE: tests/test_cdpmanager.py
  class TestCdpManager (line 23) | class TestCdpManager:
    method test_none (line 25) | def test_none(self, our_address: Address, mcd: DssDeployment):
    method test_open (line 30) | def test_open(self, our_address: Address, mcd: DssDeployment):
    method test_one (line 38) | def test_one(self, our_address: Address, mcd: DssDeployment):

FILE: tests/test_dsrmanager.py
  function mint_dai (line 28) | def mint_dai(mcd: DssDeployment, amount: Wad, ilkName: str, our_address:...
  class TestDsrManager (line 51) | class TestDsrManager:
    method test_getters (line 53) | def test_getters(self, mcd: DssDeployment):
    method test_join (line 61) | def test_join(self, mcd: DssDeployment, our_address: Address):
    method test_supply_pie_dai (line 76) | def test_supply_pie_dai(self, mcd: DssDeployment, our_address: Address):
    method test_exit (line 92) | def test_exit(self, mcd: DssDeployment, our_address: Address):

FILE: tests/test_dss.py
  function urn (line 37) | def urn(our_address: Address, mcd: DssDeployment):
  function wrap_eth (line 45) | def wrap_eth(mcd: DssDeployment, address: Address, amount: Wad):
  function mint_mkr (line 56) | def mint_mkr(mkr: DSToken, recipient_address: Address, amount: Wad):
  function get_collateral_price (line 69) | def get_collateral_price(collateral: Collateral):
  function set_collateral_price (line 74) | def set_collateral_price(mcd: DssDeployment, collateral: Collateral, pri...
  function frob (line 90) | def frob(mcd: DssDeployment, collateral: Collateral, address: Address, d...
  function max_dart (line 112) | def max_dart(mcd: DssDeployment, collateral: Collateral, our_address: Ad...
  function cleanup_urn (line 144) | def cleanup_urn(mcd: DssDeployment, collateral: Collateral, address: Add...
  function bite (line 177) | def bite(web3: Web3, mcd: DssDeployment, our_address: Address):
  function bite_event (line 201) | def bite_event(web3: Web3, mcd: DssDeployment, our_address: Address):
  class TestConfig (line 207) | class TestConfig:
    method test_from_json (line 208) | def test_from_json(self, web3: Web3, mcd: DssDeployment):
    method test_to_json (line 215) | def test_to_json(self, web3: Web3, mcd: DssDeployment):
    method test_from_node (line 222) | def test_from_node(self, web3: Web3):
    method test_collaterals (line 226) | def test_collaterals(self, mcd):
    method test_account_transfers (line 237) | def test_account_transfers(self, web3: Web3, mcd, our_address, other_a...
    method test_get_active_auctions (line 256) | def test_get_active_auctions(self, mcd):
  class TestVat (line 263) | class TestVat:
    method ensure_clean_urn (line 265) | def ensure_clean_urn(mcd: DssDeployment, collateral: Collateral, addre...
    method test_getters (line 275) | def test_getters(self, mcd):
    method test_ilk (line 278) | def test_ilk(self, mcd):
    method test_gem (line 289) | def test_gem(self, web3: Web3, mcd: DssDeployment, our_address: Address):
    method test_gem_join (line 313) | def test_gem_join(self, mcd: DssDeployment):
    method test_dai (line 322) | def test_dai(self, mcd, urn):
    method test_sin (line 326) | def test_sin(self, mcd, urn):
    method test_debt (line 331) | def test_debt(self, mcd):
    method test_urn (line 336) | def test_urn(self, urn):
    method test_frob_noop (line 343) | def test_frob_noop(self, mcd, our_address):
    method test_frob_add_ink (line 354) | def test_frob_add_ink(self, mcd, our_address):
    method test_frob_add_art (line 370) | def test_frob_add_art(self, mcd, our_address: Address):
    method test_frob_other_account (line 386) | def test_frob_other_account(self, web3, mcd, other_address):
    method test_past_frob (line 408) | def test_past_frob(self, mcd, our_address, other_address):
    method test_heal (line 464) | def test_heal(self, mcd):
    method test_flux (line 467) | def test_flux(self, mcd, our_address, other_address):
    method test_move (line 486) | def test_move(self, mcd, our_address, other_address):
    method test_fork (line 515) | def test_fork(self, mcd, our_address, other_address):
  class TestCat (line 550) | class TestCat:
    method test_getters (line 551) | def test_getters(self, mcd):
  class TestDog (line 564) | class TestDog:
    method test_getters (line 565) | def test_getters(self, mcd):
  class TestSpotter (line 580) | class TestSpotter:
    method test_mat (line 581) | def test_mat(self, mcd):
  class TestVow (line 591) | class TestVow:
    method test_getters (line 592) | def test_getters(self, mcd):
    method test_empty_flog (line 607) | def test_empty_flog(self, mcd):
    method test_heal (line 610) | def test_heal(self, mcd):
    method test_kiss (line 613) | def test_kiss(self, mcd):
  class TestJug (line 617) | class TestJug:
    method test_getters (line 618) | def test_getters(self, mcd, our_address):
    method test_drip (line 627) | def test_drip(self, mcd):
  class TestPot (line 639) | class TestPot:
    method test_getters (line 640) | def test_getters(self, mcd):
    method test_drip (line 649) | def test_drip(self, mcd):
  class TestOsm (line 660) | class TestOsm:
    method test_price (line 661) | def test_price(self, web3, mcd):
  class TestMcd (line 671) | class TestMcd:
    method test_healthy_cdp (line 672) | def test_healthy_cdp(self, mcd, our_address):
    method test_faucet (line 736) | def test_faucet(self, mcd, our_address):
    method test_empty_auctions_collection (line 743) | def test_empty_auctions_collection(self, mcd):

FILE: tests/test_etherdelta.py
  class TestEtherDelta (line 32) | class TestEtherDelta:
    method setup_method (line 33) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 49) | def test_fail_when_no_contract_under_that_address(self):
    method test_addresses (line 54) | def test_addresses(self):
    method test_fees (line 60) | def test_fees(self):
    method test_deposit_and_withdraw_eth (line 66) | def test_deposit_and_withdraw_eth(self):
    method test_deposit_and_withdraw_token (line 79) | def test_deposit_and_withdraw_token(self):
    method test_offchain_order_happy_path (line 95) | def test_offchain_order_happy_path(self):
    method test_no_past_events_on_startup (line 147) | def test_no_past_events_on_startup(self):
    method test_past_take (line 150) | def test_past_take(self):
    method test_order_comparison (line 175) | def test_order_comparison(self):
    method test_order_hashable (line 191) | def test_order_hashable(self):
    method test_should_have_printable_representation (line 200) | def test_should_have_printable_representation(self):
  class TestEtherDeltaApi (line 204) | class TestEtherDeltaApi:
    method setup_method (line 205) | def setup_method(self):
    method test_should_have_printable_representation (line 213) | def test_should_have_printable_representation(self):

FILE: tests/test_feed.py
  class TestDSValue (line 25) | class TestDSValue:
    method setup_method (line 26) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 31) | def test_fail_when_no_contract_under_that_address(self):
    method test_address (line 36) | def test_address(self):
    method test_no_value_after_deploy (line 39) | def test_no_value_after_deploy(self):
    method test_poke (line 49) | def test_poke(self):
    method test_poke_with_int (line 64) | def test_poke_with_int(self):
    method test_void (line 76) | def test_void(self):
    method test_should_have_printable_representation (line 87) | def test_should_have_printable_representation(self):

FILE: tests/test_gas.py
  class TestGasPrice (line 26) | class TestGasPrice:
    method test_not_implemented (line 27) | def test_not_implemented(self):
    method test_gwei (line 31) | def test_gwei(self):
  class TestDefaultGasPrice (line 35) | class TestDefaultGasPrice:
    method test_should_always_be_default (line 36) | def test_should_always_be_default(self):
  class TestNodeAwareGasPrice (line 46) | class TestNodeAwareGasPrice:
    class DumbSampleImplementation (line 47) | class DumbSampleImplementation(NodeAwareGasPrice):
      method get_gas_price (line 48) | def get_gas_price(self, time_elapsed: int) -> Optional[int]:
    class BadImplementation (line 51) | class BadImplementation(NodeAwareGasPrice):
    method test_retrieve_node_gas_price (line 54) | def test_retrieve_node_gas_price(self, web3):
    method test_not_implemented (line 59) | def test_not_implemented(self, web3):
  class TestFixedGasPrice (line 68) | class TestFixedGasPrice:
    method test_gas_price_should_stay_the_same (line 69) | def test_gas_price_should_stay_the_same(self):
    method test_gas_price_should_be_updated_by_update_gas_price_method (line 84) | def test_gas_price_should_be_updated_by_update_gas_price_method(self):
  class TestIncreasingGasPrice (line 107) | class TestIncreasingGasPrice:
    method test_gas_price_should_increase_with_time (line 108) | def test_gas_price_should_increase_with_time(self):
    method test_gas_price_should_obey_max_value (line 121) | def test_gas_price_should_obey_max_value(self):
    method test_should_require_positive_initial_price (line 136) | def test_should_require_positive_initial_price(self):
    method test_should_require_positive_increase_by_value (line 143) | def test_should_require_positive_increase_by_value(self):
    method test_should_require_positive_every_secs_value (line 150) | def test_should_require_positive_every_secs_value(self):
    method test_should_require_positive_max_price_if_provided (line 157) | def test_should_require_positive_max_price_if_provided(self):
  class TestGeometricGasPrice (line 165) | class TestGeometricGasPrice:
    method test_gas_price_should_increase_with_time (line 166) | def test_gas_price_should_increase_with_time(self):
    method test_gas_price_should_obey_max_value (line 180) | def test_gas_price_should_obey_max_value(self):
    method test_behaves_with_realistic_values (line 195) | def test_behaves_with_realistic_values(self):
    method test_should_require_positive_initial_price (line 210) | def test_should_require_positive_initial_price(self):
    method test_should_require_positive_every_secs_value (line 217) | def test_should_require_positive_every_secs_value(self):
    method test_should_require_positive_coefficient (line 224) | def test_should_require_positive_coefficient(self):
    method test_should_require_positive_max_price_if_provided (line 234) | def test_should_require_positive_max_price_if_provided(self):
    method test_max_price_should_exceed_initial_price (line 241) | def test_max_price_should_exceed_initial_price(self):

FILE: tests/test_general.py
  class TestConnect (line 31) | class TestConnect:
    method test_connect_to_testchain (line 32) | def test_connect_to_testchain(self, our_address):
    method test_unsupported_url (line 45) | def test_unsupported_url(self):
  class TestAddress (line 50) | class TestAddress:
    method test_creation_from_various_representations (line 51) | def test_creation_from_various_representations(self):
    method test_creation_from_another_address (line 58) | def test_creation_from_another_address(self):
    method test_should_fail_creation_from_invalid_representation (line 65) | def test_should_fail_creation_from_invalid_representation(self):
    method test_as_bytes (line 74) | def test_as_bytes(self):
    method test_string_value (line 79) | def test_string_value(self):
    method test_repr (line 84) | def test_repr(self):
    method test_should_be_hashable (line 89) | def test_should_be_hashable(self):
    method test_equality (line 92) | def test_equality(self):
    method test_ordering (line 103) | def test_ordering(self):
  class TestCalldata (line 120) | class TestCalldata:
    method test_creation (line 121) | def test_creation(self):
    method test_creation_from_bytes (line 125) | def test_creation_from_bytes(self):
    method test_should_fail_creation_from_invalid_calldata (line 129) | def test_should_fail_creation_from_invalid_calldata(self):
    method test_as_bytes (line 134) | def test_as_bytes(self):
    method test_string_value (line 138) | def test_string_value(self):
    method test_repr (line 142) | def test_repr(self):
    method test_should_be_hashable (line 146) | def test_should_be_hashable(self):
    method test_equality (line 149) | def test_equality(self):
    method test_from_signature (line 160) | def test_from_signature(self, web3):
    method test_from_contract_abi (line 186) | def test_from_contract_abi(self, web3):
  class TestReceipt (line 201) | class TestReceipt:
    method receipt_success (line 203) | def receipt_success(self) -> dict:
    method receipt_failed (line 250) | def receipt_failed(self) -> dict:
    method test_parsing_receipt (line 262) | def test_parsing_receipt(self, receipt_success):
    method test_should_recognize_successful_and_failed_transactions (line 276) | def test_should_recognize_successful_and_failed_transactions(self, rec...
  class TestTransfer (line 282) | class TestTransfer:
    method test_equality (line 283) | def test_equality(self):

FILE: tests/test_general2.py
  class TestTransact (line 31) | class TestTransact:
    method setup_method (line 32) | def setup_method(self):
    method test_can_only_execute_once (line 41) | def test_can_only_execute_once(self):
    method test_can_only_execute_once_even_if_tx_failed (line 51) | def test_can_only_execute_once_even_if_tx_failed(self):
    method test_should_update_status_when_finished (line 65) | def test_should_update_status_when_finished(self):
    method test_should_update_status_to_finished_even_if_tx_failed (line 75) | def test_should_update_status_to_finished_even_if_tx_failed(self):
    method test_default_gas (line 88) | def test_default_gas(self):
    method test_default_gas_async (line 95) | def test_default_gas_async(self):
    method test_custom_gas (line 102) | def test_custom_gas(self):
    method test_custom_gas_async (line 109) | def test_custom_gas_async(self):
    method test_custom_gas_buffer (line 116) | def test_custom_gas_buffer(self):
    method test_gas_and_gas_buffer_not_allowed_at_the_same_time (line 123) | def test_gas_and_gas_buffer_not_allowed_at_the_same_time(self):
    method test_gas_and_gas_buffer_not_allowed_at_the_same_time_async (line 128) | def test_gas_and_gas_buffer_not_allowed_at_the_same_time_async(self):
    method test_custom_gas_price (line 134) | def test_custom_gas_price(self):
    method test_custom_gas_price_async (line 144) | def test_custom_gas_price_async(self):
    method test_custom_from_address (line 154) | def test_custom_from_address(self):
    method test_name_formatting (line 164) | def test_name_formatting(self):
    method test_name_formatting_with_hexstrings (line 171) | def test_name_formatting_with_hexstrings(self):
    method test_eth_transfer (line 182) | def test_eth_transfer(self):
    method test_eth_transfer_from_other_account (line 192) | def test_eth_transfer_from_other_account(self):
    method test_should_raise_exception_on_unknown_kwarg (line 204) | def test_should_raise_exception_on_unknown_kwarg(self):
  class TestTransactReplace (line 214) | class TestTransactReplace:
    method setup_method (line 215) | def setup_method(self):
    method test_transaction_replace (line 225) | async def test_transaction_replace(self):
    method test_transaction_replace_of_failed_transaction (line 266) | def test_transaction_replace_of_failed_transaction(self):
  class TestTransactRecover (line 300) | class TestTransactRecover:
    method setup_method (line 301) | def setup_method(self):
    method test_nothing_pending (line 307) | def test_nothing_pending(self):
    method test_recover_pending_tx (line 315) | async def test_recover_pending_tx(self, other_address):

FILE: tests/test_governance.py
  function mint_approve_lock (line 30) | def mint_approve_lock(mcd: DssDeployment, amount: Wad, address: Address):
  function approve_iou_free_mkr (line 40) | def approve_iou_free_mkr(mcd: DssDeployment, amount: Wad, address: Addre...
  function launch_chief (line 48) | def launch_chief(mcd: DssDeployment, address: Address):
  class TestDSPause (line 62) | class TestDSPause:
    method setup_method (line 63) | def setup_method(self):
    method test_drop (line 75) | def test_drop(self):
    method test_exec (line 79) | def test_exec(self):
  class TestDSChief (line 83) | class TestDSChief:
    method test_launch (line 85) | def test_launch(self, mcd: DssDeployment, our_address: Address):
    method test_scenario (line 90) | def test_scenario(self, mcd: DssDeployment, our_address: Address, othe...

FILE: tests/test_keys.py
  function test_local_accounts (line 25) | def test_local_accounts():
  function test_local_accounts_register_key (line 50) | def test_local_accounts_register_key():
  function test_multiple_local_accounts (line 75) | def test_multiple_local_accounts():

FILE: tests/test_lifecycle.py
  class TestLifecycle (line 32) | class TestLifecycle:
    method setup_method (line 33) | def setup_method(self):
    method use_web3 (line 43) | def use_web3(self, with_web3: bool):
    method test_should_always_exit (line 47) | def test_should_always_exit(self, with_web3):
    method test_should_start_instantly_if_no_initial_delay (line 53) | def test_should_start_instantly_if_no_initial_delay(self, with_web3):
    method test_should_obey_initial_delay (line 67) | def test_should_obey_initial_delay(self, with_web3):
    method test_should_check_initial_checks (line 81) | def test_should_check_initial_checks(self, with_web3):
    method test_should_time_out_initial_checks_even_if_they_constantly_return_false (line 97) | def test_should_time_out_initial_checks_even_if_they_constantly_return...
    method test_should_call_startup_callback (line 111) | def test_should_call_startup_callback(self, with_web3):
    method test_should_fail_to_register_two_startup_callbacks (line 124) | def test_should_fail_to_register_two_startup_callbacks(self, with_web3):
    method test_should_call_shutdown_callback (line 132) | def test_should_call_shutdown_callback(self, with_web3):
    method test_should_fail_to_register_two_shutdown_callbacks (line 148) | def test_should_fail_to_register_two_shutdown_callbacks(self, with_web3):
    method test_should_fail_to_register_two_block_callbacks (line 155) | def test_should_fail_to_register_two_block_callbacks(self):
    method test_should_fail_to_register_block_callback_if_no_web3 (line 162) | def test_should_fail_to_register_block_callback_if_no_web3(self):
    method test_every (line 169) | def test_every(self, with_web3):
    method test_on_event_fires_whenever_event_triggered (line 190) | def test_on_event_fires_whenever_event_triggered(self, with_web3):
    method test_on_event_fires_every_min_frequency_if_event_not_triggered (line 215) | def test_on_event_fires_every_min_frequency_if_event_not_triggered(sel...
    method test_every_does_not_start_operating_until_startup_callback_is_finished (line 236) | def test_every_does_not_start_operating_until_startup_callback_is_fini...
    method test_event_does_not_start_operating_until_startup_callback_is_finished (line 258) | def test_event_does_not_start_operating_until_startup_callback_is_fini...
    method test_every_should_not_fire_when_keeper_is_already_terminating (line 280) | def test_every_should_not_fire_when_keeper_is_already_terminating(self...
    method test_events_should_not_fire_when_keeper_is_already_terminating (line 301) | def test_events_should_not_fire_when_keeper_is_already_terminating(sel...
    method test_should_not_call_shutdown_until_every_timer_has_finished (line 322) | def test_should_not_call_shutdown_until_every_timer_has_finished(self,...
    method test_should_not_call_shutdown_until_every_event_has_finished (line 349) | def test_should_not_call_shutdown_until_every_event_has_finished(self,...

FILE: tests/test_model.py
  class TestToken (line 22) | class TestToken:
    method setup_class (line 23) | def setup_class(self):
    method test_convert (line 26) | def test_convert(self):
    method test_min_amount (line 35) | def test_min_amount(self):

FILE: tests/test_numeric.py
  class TestWad (line 25) | class TestWad:
    method test_should_support_negative_values (line 26) | def test_should_support_negative_values(self):
    method test_should_support_values_greater_than_uint256 (line 29) | def test_should_support_values_greater_than_uint256(self):
    method test_should_instantiate_from_a_wad (line 34) | def test_should_instantiate_from_a_wad(self):
    method test_should_instantiate_from_a_ray (line 37) | def test_should_instantiate_from_a_ray(self):
    method test_should_instantiate_from_an_int (line 41) | def test_should_instantiate_from_an_int(self):
    method test_should_fail_to_instantiate_from_a_float (line 44) | def test_should_fail_to_instantiate_from_a_float(self):
    method test_should_format_to_string_nicely (line 48) | def test_should_format_to_string_nicely(self):
    method test_should_have_nice_printable_representation (line 56) | def test_should_have_nice_printable_representation(self):
    method test_add (line 60) | def test_add(self):
    method test_add_should_not_work_with_rays (line 63) | def test_add_should_not_work_with_rays(self):
    method test_add_should_not_work_with_ints (line 67) | def test_add_should_not_work_with_ints(self):
    method test_subtract (line 71) | def test_subtract(self):
    method test_subtract_should_not_work_with_rays (line 75) | def test_subtract_should_not_work_with_rays(self):
    method test_modulo (line 79) | def test_modulo(self):
    method test_modulo_should_not_work_with_rays (line 84) | def test_modulo_should_not_work_with_rays(self):
    method test_multiply (line 88) | def test_multiply(self):
    method test_multiply_by_ray (line 94) | def test_multiply_by_ray(self):
    method test_multiply_by_int (line 102) | def test_multiply_by_int(self):
    method test_should_fail_to_multiply_by_float (line 106) | def test_should_fail_to_multiply_by_float(self):
    method test_divide (line 110) | def test_divide(self):
    method test_should_fail_to_divide_by_rays (line 118) | def test_should_fail_to_divide_by_rays(self):
    method test_should_fail_to_divide_by_ints (line 122) | def test_should_fail_to_divide_by_ints(self):
    method test_should_support_abs (line 126) | def test_should_support_abs(self):
    method test_should_compare_wads_with_each_other (line 131) | def test_should_compare_wads_with_each_other(self):
    method test_should_reject_comparison_with_rays (line 141) | def test_should_reject_comparison_with_rays(self):
    method test_should_reject_comparison_with_ints (line 159) | def test_should_reject_comparison_with_ints(self):
    method test_should_cast_to_int (line 177) | def test_should_cast_to_int(self):
    method test_should_cast_to_float (line 185) | def test_should_cast_to_float(self):
    method test_should_be_hashable (line 193) | def test_should_be_hashable(self):
    method test_min_value (line 196) | def test_min_value(self):
    method test_min_value_should_reject_comparison_with_rays (line 201) | def test_min_value_should_reject_comparison_with_rays(self):
    method test_min_value_should_reject_comparison_with_ints (line 207) | def test_min_value_should_reject_comparison_with_ints(self):
    method test_max_value (line 213) | def test_max_value(self):
    method test_max_value_should_reject_comparison_with_rays (line 218) | def test_max_value_should_reject_comparison_with_rays(self):
    method test_max_value_should_reject_comparison_with_ints (line 224) | def test_max_value_should_reject_comparison_with_ints(self):
    method test_round (line 230) | def test_round(self):
    method test_round_inequality (line 235) | def test_round_inequality(self):
    method test_square_root (line 243) | def test_square_root(self):
  class TestRay (line 249) | class TestRay:
    method test_should_support_negative_values (line 250) | def test_should_support_negative_values(self):
    method test_should_support_values_greater_than_uint256 (line 253) | def test_should_support_values_greater_than_uint256(self):
    method test_should_instantiate_from_a_ray (line 258) | def test_should_instantiate_from_a_ray(self):
    method test_should_instantiate_from_a_wad (line 261) | def test_should_instantiate_from_a_wad(self):
    method test_should_instantiate_from_an_int (line 264) | def test_should_instantiate_from_an_int(self):
    method test_should_fail_to_instantiate_from_a_float (line 267) | def test_should_fail_to_instantiate_from_a_float(self):
    method test_should_format_to_string_nicely (line 271) | def test_should_format_to_string_nicely(self):
    method test_should_have_nice_printable_representation (line 279) | def test_should_have_nice_printable_representation(self):
    method test_add (line 283) | def test_add(self):
    method test_add_should_not_work_with_wads (line 286) | def test_add_should_not_work_with_wads(self):
    method test_add_should_not_work_with_ints (line 290) | def test_add_should_not_work_with_ints(self):
    method test_subtract (line 294) | def test_subtract(self):
    method test_subtract_should_not_work_with_wads (line 298) | def test_subtract_should_not_work_with_wads(self):
    method test_modulo (line 302) | def test_modulo(self):
    method test_modulo_should_not_work_with_wads (line 307) | def test_modulo_should_not_work_with_wads(self):
    method test_multiply (line 311) | def test_multiply(self):
    method test_multiply_by_wad (line 317) | def test_multiply_by_wad(self):
    method test_multiply_by_int (line 324) | def test_multiply_by_int(self):
    method test_should_fail_to_multiply_by_float (line 328) | def test_should_fail_to_multiply_by_float(self):
    method test_divide (line 332) | def test_divide(self):
    method test_should_fail_to_divide_by_wads (line 340) | def test_should_fail_to_divide_by_wads(self):
    method test_should_fail_to_divide_by_ints (line 344) | def test_should_fail_to_divide_by_ints(self):
    method test_should_support_abs (line 348) | def test_should_support_abs(self):
    method test_should_compare_rays_with_each_other (line 353) | def test_should_compare_rays_with_each_other(self):
    method test_should_reject_comparison_with_wads (line 363) | def test_should_reject_comparison_with_wads(self):
    method test_should_reject_comparison_with_ints (line 381) | def test_should_reject_comparison_with_ints(self):
    method test_should_cast_to_int (line 399) | def test_should_cast_to_int(self):
    method test_should_cast_to_float (line 407) | def test_should_cast_to_float(self):
    method test_should_be_hashable (line 415) | def test_should_be_hashable(self):
    method test_min_value (line 418) | def test_min_value(self):
    method test_min_value_should_reject_comparison_with_wads (line 423) | def test_min_value_should_reject_comparison_with_wads(self):
    method test_min_value_should_reject_comparison_with_ints (line 429) | def test_min_value_should_reject_comparison_with_ints(self):
    method test_max_value (line 435) | def test_max_value(self):
    method test_max_value_should_reject_comparison_with_wads (line 440) | def test_max_value_should_reject_comparison_with_wads(self):
    method test_max_value_should_reject_comparison_with_ints (line 446) | def test_max_value_should_reject_comparison_with_ints(self):
    method test_round (line 452) | def test_round(self):
    method test_square_root (line 457) | def test_square_root(self):
  class TestRad (line 463) | class TestRad:
    method test_should_support_negative_values (line 464) | def test_should_support_negative_values(self):
    method test_should_support_values_greater_than_uint256 (line 467) | def test_should_support_values_greater_than_uint256(self):
    method test_should_instantiate_from_a_rad (line 472) | def test_should_instantiate_from_a_rad(self):
    method test_should_instantiate_from_a_wad (line 475) | def test_should_instantiate_from_a_wad(self):
    method test_should_instantiate_from_a_ray (line 478) | def test_should_instantiate_from_a_ray(self):
    method test_should_instantiate_from_an_int (line 481) | def test_should_instantiate_from_an_int(self):
    method test_should_fail_to_instantiate_from_a_float (line 484) | def test_should_fail_to_instantiate_from_a_float(self):
    method test_should_format_to_string_nicely (line 488) | def test_should_format_to_string_nicely(self):
    method test_should_have_nice_printable_representation (line 496) | def test_should_have_nice_printable_representation(self):
    method test_add (line 500) | def test_add(self):
    method test_add_should_not_work_with_wads (line 503) | def test_add_should_not_work_with_wads(self):
    method test_add_should_not_work_with_rays (line 507) | def test_add_should_not_work_with_rays(self):
    method test_add_should_not_work_with_ints (line 511) | def test_add_should_not_work_with_ints(self):
    method test_subtract (line 515) | def test_subtract(self):
    method test_subtract_should_not_work_with_wads (line 519) | def test_subtract_should_not_work_with_wads(self):
    method test_subtract_should_not_work_with_rays (line 523) | def test_subtract_should_not_work_with_rays(self):
    method test_modulo (line 527) | def test_modulo(self):
    method test_modulo_should_not_work_with_wads (line 532) | def test_modulo_should_not_work_with_wads(self):
    method test_multiply (line 536) | def test_multiply(self):
    method test_multiply_by_wad (line 542) | def test_multiply_by_wad(self):
    method test_multiply_by_ray (line 549) | def test_multiply_by_ray(self):
    method test_multiply_by_int (line 556) | def test_multiply_by_int(self):
    method test_should_fail_to_multiply_by_float (line 560) | def test_should_fail_to_multiply_by_float(self):
    method test_divide (line 564) | def test_divide(self):
    method test_should_fail_to_divide_by_wads (line 572) | def test_should_fail_to_divide_by_wads(self):
    method test_should_fail_to_divide_by_rays (line 576) | def test_should_fail_to_divide_by_rays(self):
    method test_should_fail_to_divide_by_ints (line 580) | def test_should_fail_to_divide_by_ints(self):
    method test_should_support_abs (line 584) | def test_should_support_abs(self):
    method test_should_compare_rays_with_each_other (line 589) | def test_should_compare_rays_with_each_other(self):
    method test_should_reject_comparison_with_wads (line 599) | def test_should_reject_comparison_with_wads(self):
    method test_should_reject_comparison_with_rays (line 617) | def test_should_reject_comparison_with_rays(self):
    method test_should_reject_comparison_with_ints (line 635) | def test_should_reject_comparison_with_ints(self):
    method test_should_cast_to_int (line 653) | def test_should_cast_to_int(self):
    method test_should_cast_to_float (line 661) | def test_should_cast_to_float(self):
    method test_should_be_hashable (line 669) | def test_should_be_hashable(self):
    method test_min_value (line 672) | def test_min_value(self):
    method test_min_value_should_reject_comparison_with_wads (line 677) | def test_min_value_should_reject_comparison_with_wads(self):
    method test_min_value_should_reject_comparison_with_rays (line 683) | def test_min_value_should_reject_comparison_with_rays(self):
    method test_min_value_should_reject_comparison_with_ints (line 689) | def test_min_value_should_reject_comparison_with_ints(self):
    method test_max_value (line 695) | def test_max_value(self):
    method test_max_value_should_reject_comparison_with_wads (line 700) | def test_max_value_should_reject_comparison_with_wads(self):
    method test_max_value_should_reject_comparison_with_rays (line 706) | def test_max_value_should_reject_comparison_with_rays(self):
    method test_max_value_should_reject_comparison_with_ints (line 712) | def test_max_value_should_reject_comparison_with_ints(self):
    method test_round (line 718) | def test_round(self):
    method test_square_root (line 723) | def test_square_root(self):

FILE: tests/test_oasis.py
  class OasisMockPriceOracle (line 38) | class OasisMockPriceOracle(Contract):
    method __init__ (line 44) | def __init__(self, web3: Web3, address: Address):
    method deploy (line 53) | def deploy(web3: Web3):
    method set_price (line 57) | def set_price(self, price: Wad):
    method __eq__ (line 61) | def __eq__(self, other):
    method __repr__ (line 64) | def __repr__(self):
  class GeneralMarketTest (line 68) | class GeneralMarketTest:
    method setup_method (line 69) | def setup_method(self):
    method test_approve_and_make_and_getters (line 93) | def test_approve_and_make_and_getters(self):
    method test_make_returns_new_order_ids (line 125) | def test_make_returns_new_order_ids(self):
    method test_get_orders_by_pair (line 145) | def test_get_orders_by_pair(self):
    method test_get_orders_by_maker (line 211) | def test_get_orders_by_maker(self):
    method test_get_orders_by_block (line 250) | def test_get_orders_by_block(self):
    method test_order_comparison (line 276) | def test_order_comparison(self):
    method test_order_hashable (line 301) | def test_order_hashable(self):
    method test_take_partial (line 318) | def test_take_partial(self):
    method test_remaining_sell_and_buy_amounts (line 342) | def test_remaining_sell_and_buy_amounts(self):
    method test_take_complete (line 368) | def test_take_complete(self):
    method test_kill (line 391) | def test_kill(self):
    method test_no_past_events_on_startup (line 413) | def test_no_past_events_on_startup(self):
    method test_past_make (line 419) | def test_past_make(self):
    method test_past_bump (line 445) | def test_past_bump(self):
    method test_past_take (line 472) | def test_past_take(self):
    method test_past_take_with_filter (line 503) | def test_past_take_with_filter(self):
    method test_past_kill (line 527) | def test_past_kill(self):
  class TestSimpleMarket (line 557) | class TestSimpleMarket(GeneralMarketTest):
    method setup_method (line 558) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 562) | def test_fail_when_no_contract_under_that_address(self):
    method test_should_have_printable_representation (line 567) | def test_should_have_printable_representation(self):
  class TestMatchingMarket (line 571) | class TestMatchingMarket(GeneralMarketTest):
    method setup_method (line 572) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 579) | def test_fail_when_no_contract_under_that_address(self):
    method test_simple_matching (line 584) | def test_simple_matching(self):
    method test_advanced_matching (line 602) | def test_advanced_matching(self):
    method test_should_have_printable_representation (line 639) | def test_should_have_printable_representation(self):
  class TestMatchingMarketWithSupportContract (line 643) | class TestMatchingMarketWithSupportContract(TestMatchingMarket):
    method setup_method (line 644) | def setup_method(self):
    method test_fail_when_no_support_contract_under_that_address (line 657) | def test_fail_when_no_support_contract_under_that_address(self):
  class TestMatchingMarketDecimal (line 665) | class TestMatchingMarketDecimal:
    method setup_method (line 666) | def setup_method(self):
    method test_get_orders (line 686) | def test_get_orders(self):
  class TestMatchingMarketPosition (line 704) | class TestMatchingMarketPosition:
    method setup_method (line 705) | def setup_method(self):
    method test_should_calculate_correct_order_position (line 723) | def test_should_calculate_correct_order_position(self):
    method test_should_use_correct_order_position_by_default (line 729) | def test_should_use_correct_order_position_by_default(self):
    method test_calculated_order_position_should_bring_gas_savings (line 748) | def test_calculated_order_position_should_bring_gas_savings(self):

FILE: tests/test_proxy.py
  function web3 (line 26) | def web3():
  function our_address (line 33) | def our_address(web3):
  function other_address (line 38) | def other_address(web3):
  function proxy_cache (line 43) | def proxy_cache(web3):
  function proxy_factory (line 48) | def proxy_factory(web3):
  function proxy (line 53) | def proxy(web3, proxy_cache):
  class TestProxyCache (line 57) | class TestProxyCache:
    method test_read (line 60) | def test_read(self, proxy_cache: DSProxyCache):
    method test_write_invalid (line 63) | def test_write_invalid(self, proxy_cache: DSProxyCache):
    method test_write (line 71) | def test_write(self, proxy_cache: DSProxyCache):
  class TestProxyFactory (line 79) | class TestProxyFactory:
    method test_build (line 82) | def test_build(self, proxy_factory: DSProxyFactory):
    method test_past_build (line 85) | def test_past_build(self, proxy_factory: DSProxyFactory, our_address):
    method test_build_for (line 104) | def test_build_for(self, proxy_factory: DSProxyFactory, other_address):
    method test_cache (line 118) | def test_cache(self, proxy_factory: DSProxyFactory, other_address):
  class TestProxy (line 122) | class TestProxy:
    method test_execute (line 125) | def test_execute(self, proxy: DSProxy):
    method test_execute_at (line 128) | def test_execute_at(self, proxy: DSProxy):
    method test_call (line 144) | def test_call(self, proxy: DSProxy):
    method test_call_at (line 153) | def test_call_at(self, proxy: DSProxy):

FILE: tests/test_reloadable_config.py
  class TestReloadableConfig (line 23) | class TestReloadableConfig:
    method write_sample_config (line 25) | def write_sample_config(tmpdir):
    method write_advanced_config (line 31) | def write_advanced_config(tmpdir, value):
    method write_global_config (line 37) | def write_global_config(tmpdir, val1, val2):
    method write_importing_config (line 45) | def write_importing_config(tmpdir):
    method test_should_read_simple_file (line 55) | def test_should_read_simple_file(self, tmpdir):
    method test_should_read_advanced_file (line 63) | def test_should_read_advanced_file(self, tmpdir):
    method test_should_read_file_again_if_changed (line 72) | def test_should_read_file_again_if_changed(self, tmpdir):
    method test_should_import_other_config_file (line 98) | def test_should_import_other_config_file(self, tmpdir):
    method test_should_reevaluate_if_other_config_file_changed (line 108) | def test_should_reevaluate_if_other_config_file_changed(self, tmpdir):

FILE: tests/test_sai.py
  class TestTub (line 28) | class TestTub:
    method test_fail_when_no_contract_under_that_address (line 29) | def test_fail_when_no_contract_under_that_address(self, deployment: De...
    method test_tap (line 34) | def test_tap(self, deployment: Deployment):
    method test_era (line 38) | def test_era(self, deployment: Deployment):
    method test_join_and_pie_and_exit (line 46) | def test_join_and_pie_and_exit(self, deployment: Deployment):
    method test_mold_cap_and_cap (line 67) | def test_mold_cap_and_cap(self, deployment: Deployment):
    method test_mold_tax_and_tax (line 77) | def test_mold_tax_and_tax(self, deployment: Deployment):
    method test_mold_mat_and_mat (line 87) | def test_mold_mat_and_mat(self, deployment: Deployment):
    method test_mold_axe_and_axe (line 97) | def test_mold_axe_and_axe(self, deployment: Deployment):
    method test_sai (line 108) | def test_sai(self, deployment: Deployment):
    method test_sin (line 111) | def test_sin(self, deployment: Deployment):
    method test_gem (line 114) | def test_gem(self, deployment: Deployment):
    method test_skr (line 117) | def test_skr(self, deployment: Deployment):
    method test_gov (line 120) | def test_gov(self, deployment: Deployment):
    method test_vox (line 123) | def test_vox(self, deployment: Deployment):
    method test_pip_and_pep (line 126) | def test_pip_and_pep(self, deployment: Deployment):
    method test_pit (line 130) | def test_pit(self, deployment: Deployment):
    method test_per (line 133) | def test_per(self, deployment: Deployment):
    method test_tag (line 136) | def test_tag(self, deployment: Deployment):
    method test_drip_and_chi_and_rho (line 143) | def test_drip_and_chi_and_rho(self, deployment: Deployment):
    method test_open_and_cupi (line 157) | def test_open_and_cupi(self, deployment: Deployment):
    method test_cups (line 164) | def test_cups(self, deployment: Deployment):
    method test_not_empty_cups (line 173) | def test_not_empty_cups(self, deployment: Deployment):
    method test_safe (line 190) | def test_safe(self, deployment: Deployment):
    method test_ink (line 202) | def test_ink(self, deployment: Deployment):
    method test_lad (line 209) | def test_lad(self, deployment: Deployment):
    method test_give (line 216) | def test_give(self, deployment: Deployment):
    method test_shut (line 226) | def test_shut(self, deployment: Deployment):
    method test_lock_and_free (line 237) | def test_lock_and_free(self, deployment: Deployment):
    method test_draw_and_tab_and_din_and_wipe (line 258) | def test_draw_and_tab_and_din_and_wipe(self, deployment: Deployment):
    method test_bite_and_safe (line 284) | def test_bite_and_safe(self, deployment: Deployment):
    method test_mold_gap_and_gap (line 310) | def test_mold_gap_and_gap(self, deployment: Deployment):
    method test_bid_and_ask (line 320) | def test_bid_and_ask(self, deployment: Deployment):
    method test_comparison (line 328) | def test_comparison(self, deployment: Deployment):
  class TestTap (line 334) | class TestTap:
    method test_fail_when_no_contract_under_that_address (line 335) | def test_fail_when_no_contract_under_that_address(self, deployment: De...
    method test_tub (line 340) | def test_tub(self, deployment: Deployment):
    method test_sai (line 343) | def test_sai(self, deployment: Deployment):
    method test_sin (line 346) | def test_sin(self, deployment: Deployment):
    method test_skr (line 349) | def test_skr(self, deployment: Deployment):
    method test_mold_gap_and_gap (line 352) | def test_mold_gap_and_gap(self, deployment: Deployment):
    method test_woe (line 362) | def test_woe(self, deployment: Deployment):
    method test_fog (line 365) | def test_fog(self, deployment: Deployment):
    method test_joy (line 368) | def test_joy(self, deployment: Deployment):
    method test_s2s_and_bid_and_ask (line 371) | def test_s2s_and_bid_and_ask(self, deployment: Deployment):
    method test_joy_and_boom (line 381) | def test_joy_and_boom(self, deployment: Deployment):
    method test_fog_and_woe_and_bust (line 412) | def test_fog_and_woe_and_bust(self, deployment: Deployment):
    method test_cash (line 442) | def test_cash(self, deployment: Deployment):
    method test_mock (line 471) | def test_mock(self, deployment: Deployment):
    method test_comparison (line 494) | def test_comparison(self, deployment: Deployment):
  class TestTop (line 501) | class TestTop:
    method test_fail_when_no_contract_under_that_address (line 502) | def test_fail_when_no_contract_under_that_address(self, deployment: De...
    method test_comparison (line 507) | def test_comparison(self, deployment: Deployment):
    method test_default_fix (line 513) | def test_default_fix(self, deployment: Deployment):
    method test_cage (line 517) | def test_cage(self, deployment: Deployment):
  class TestVox (line 535) | class TestVox:
    method test_fail_when_no_contract_under_that_address (line 536) | def test_fail_when_no_contract_under_that_address(self, deployment: De...
    method test_comparison (line 541) | def test_comparison(self, deployment: Deployment):
    method test_era (line 548) | def test_era(self, deployment: Deployment):
    method test_default_par (line 556) | def test_default_par(self, deployment: Deployment):

FILE: tests/test_savings.py
  function dsr (line 29) | def dsr(our_address: Address, mcd: DssDeployment) -> Dsr:
  function test_proxy (line 34) | def test_proxy(dsr):
  function test_join_and_exit (line 42) | def test_join_and_exit(dsr):

FILE: tests/test_shutdown.py
  function open_cdp (line 33) | def open_cdp(mcd: DssDeployment, collateral: Collateral, address: Address):
  function create_flap_auction (line 47) | def create_flap_auction(mcd: DssDeployment, deployment_address: Address,...
  class TestShutdownModule (line 69) | class TestShutdownModule:
    method test_init (line 72) | def test_init(self, mcd, deployment_address, our_address):
    method test_join (line 86) | def test_join(self, mcd, our_address):
    method test_fire (line 105) | def test_fire(self, mcd, our_address):
  class TestEnd (line 112) | class TestEnd:
    method test_init (line 115) | def test_init(self, mcd):
    method test_getters (line 120) | def test_getters(self, mcd):
    method test_cage (line 133) | def test_cage(self, mcd):
    method test_yank (line 141) | def test_yank(self, mcd):
    method test_skim (line 158) | def test_skim(self, mcd, our_address):
    method test_close_cdp (line 176) | def test_close_cdp(self, web3, mcd, our_address):
    method test_pack (line 192) | def test_pack(self, mcd, our_address):

FILE: tests/test_sign.py
  function test_signing (line 26) | def test_signing():
  function test_signing_with_key_and_rpc_should_return_same_result (line 39) | def test_signing_with_key_and_rpc_should_return_same_result():

FILE: tests/test_token.py
  class TestERC20Token (line 28) | class TestERC20Token:
    method setup_method (line 29) | def setup_method(self):
    method test_fail_when_no_token_with_that_address (line 38) | def test_fail_when_no_token_with_that_address(self):
    method test_symbol_for_dstoken_which_returns_bytes32 (line 42) | def test_symbol_for_dstoken_which_returns_bytes32(self):
    method test_total_supply (line 45) | def test_total_supply(self):
    method test_balance_of (line 48) | def test_balance_of(self):
    method test_balance_at_block (line 52) | def test_balance_at_block(self):
    method test_transfer (line 69) | def test_transfer(self):
    method test_transfer_async (line 78) | def test_transfer_async(self):
    method test_transfer_failed (line 87) | def test_transfer_failed(self):
    method test_transfer_failed_async (line 96) | def test_transfer_failed_async(self):
    method test_transfer_out_of_gas (line 105) | def test_transfer_out_of_gas(self):
    method test_transfer_out_of_gas_async (line 114) | def test_transfer_out_of_gas_async(self):
    method test_transfer_generates_transfer (line 123) | def test_transfer_generates_transfer(self):
    method test_transfer_from (line 134) | def test_transfer_from(self):
    method test_allowance_of (line 144) | def test_allowance_of(self):
    method test_approve (line 147) | def test_approve(self):
    method test_equals (line 154) | def test_equals(self):
    method test_should_have_printable_representation (line 166) | def test_should_have_printable_representation(self):
  class TestDSToken (line 171) | class TestDSToken:
    method setup_method (line 172) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 179) | def test_fail_when_no_contract_under_that_address(self):
    method test_authority (line 184) | def test_authority(self):
    method test_mint (line 194) | def test_mint(self):
    method test_mint_to_other_address (line 201) | def test_mint_to_other_address(self):
    method test_mint_generates_transfer (line 208) | def test_mint_generates_transfer(self):
    method test_burn (line 219) | def test_burn(self):
    method test_burn_from_other_address (line 229) | def test_burn_from_other_address(self):
    method test_burn_generates_transfer (line 240) | def test_burn_generates_transfer(self):
    method test_should_have_printable_representation (line 254) | def test_should_have_printable_representation(self):
  class TestDSEthToken (line 258) | class TestDSEthToken:
    method setup_method (line 259) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 265) | def test_fail_when_no_contract_under_that_address(self):
    method test_deposit (line 270) | def test_deposit(self):
    method test_withdraw (line 277) | def test_withdraw(self):
    method test_should_have_printable_representation (line 287) | def test_should_have_printable_representation(self):

FILE: tests/test_transactional.py
  class TestTxManager (line 28) | class TestTxManager:
    method setup_method (line 29) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 40) | def test_fail_when_no_contract_under_that_address(self):
    method test_owner (line 45) | def test_owner(self):
    method test_approve (line 48) | def test_approve(self):
    method test_execute_zero_calls (line 60) | def test_execute_zero_calls(self):
    method test_execute_one_call (line 70) | def test_execute_one_call(self):
    method test_execute_one_call_fails_if_no_approval (line 83) | def test_execute_one_call_fails_if_no_approval(self):
    method test_execute_multiple_calls_with_multiple_tokens (line 96) | def test_execute_multiple_calls_with_multiple_tokens(self):
    method test_should_have_printable_representation (line 113) | def test_should_have_printable_representation(self):

FILE: tests/test_util.py
  function async_return (line 30) | async def async_return(result):
  function async_exception (line 34) | async def async_exception():
  function mocked_web3 (line 39) | def mocked_web3(block_0_hash: str) -> Web3:
  function test_chain_should_recognize_ethlive (line 52) | def test_chain_should_recognize_ethlive():
  function test_chain_should_recognize_kovan (line 60) | def test_chain_should_recognize_kovan():
  function test_chain_should_recognize_ropsten (line 68) | def test_chain_should_recognize_ropsten():
  function test_chain_should_recognize_morden (line 76) | def test_chain_should_recognize_morden():
  function test_chain_should_report_unknown_chains_as_unknown (line 84) | def test_chain_should_report_unknown_chains_as_unknown():
  function mocked_web3_transaction_count (line 92) | def mocked_web3_transaction_count(address: Address, latest: int, pending...
  function test_synchronize_should_return_empty_list_for_no_futures (line 108) | def test_synchronize_should_return_empty_list_for_no_futures():
  function test_synchronize_should_return_results_of_all_async_calls (line 112) | def test_synchronize_should_return_results_of_all_async_calls():
  function test_synchronize_should_pass_exceptions (line 118) | def test_synchronize_should_pass_exceptions():
  function test_int_to_bytes32 (line 123) | def test_int_to_bytes32():
  function test_bytes_to_int (line 145) | def test_bytes_to_int():
  function test_bytes_to_int_from_string (line 175) | def test_bytes_to_int_from_string():
  function test_bytes_to_int_from_int_should_fail (line 183) | def test_bytes_to_int_from_int_should_fail():
  function test_bytes_to_hexstring (line 188) | def test_bytes_to_hexstring():
  function test_hexstring_to_bytes (line 194) | def test_hexstring_to_bytes():
  class TestAsyncCallback (line 200) | class TestAsyncCallback:
    method callbacks (line 202) | def callbacks(self):
    method test_should_call_callback (line 215) | def test_should_call_callback(self, callbacks):
    method test_should_not_call_callback_if_previous_one_is_still_running (line 226) | def test_should_not_call_callback_if_previous_one_is_still_running(sel...
    method test_should_call_callback_again_if_previous_one_is_finished (line 242) | def test_should_call_callback_again_if_previous_one_is_finished(self, ...
    method test_should_wait_for_the_callback_to_finish (line 259) | def test_should_wait_for_the_callback_to_finish(self, callbacks):
    method test_should_call_on_start_and_on_finish_before_and_after_the_callback (line 271) | def test_should_call_on_start_and_on_finish_before_and_after_the_callb...

FILE: tests/test_vault.py
  class TestDSVault (line 25) | class TestDSVault:
    method setup_method (line 26) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 32) | def test_fail_when_no_contract_under_that_address(self):
    method test_authority (line 37) | def test_authority(self):
    method test_should_have_printable_representation (line 47) | def test_should_have_printable_representation(self):

FILE: tests/test_zrx.py
  class TestZrx (line 36) | class TestZrx:
    method setup_method (line 37) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 53) | def test_fail_when_no_contract_under_that_address(self):
    method test_correct_deployment (line 58) | def test_correct_deployment(self):
    method test_approval (line 65) | def test_approval(self):
    method test_create_order (line 77) | def test_create_order(self):
    method test_get_order_hash (line 101) | def test_get_order_hash(self):
    method test_sign_order (line 115) | def test_sign_order(self):
    method test_cancel_order (line 132) | def test_cancel_order(self):
    method test_fill_order (line 152) | def test_fill_order(self):
    method test_remaining_buy_amount_and_remaining_sell_amount (line 172) | def test_remaining_buy_amount_and_remaining_sell_amount(self):
    method test_past_fill (line 194) | def test_past_fill(self):
    method test_past_cancel (line 221) | def test_past_cancel(self):
    method test_should_have_printable_representation (line 245) | def test_should_have_printable_representation(self):
  class TestOrder (line 249) | class TestOrder:
    method test_should_be_comparable (line 250) | def test_should_be_comparable(self):
    method test_should_be_hashable (line 301) | def test_should_be_hashable(self):
    method test_parse_signed_json_order (line 323) | def test_parse_signed_json_order(self):
    method test_parse_unsigned_json_order (line 366) | def test_parse_unsigned_json_order(self):
    method test_serialize_order_to_json_without_fees (line 404) | def test_serialize_order_to_json_without_fees(self):
    method test_serialize_order_to_json (line 439) | def test_serialize_order_to_json(self):

FILE: tests/test_zrxv2.py
  class TestZrxV2 (line 38) | class TestZrxV2:
    method setup_method (line 39) | def setup_method(self):
    method test_fail_when_no_contract_under_that_address (line 58) | def test_fail_when_no_contract_under_that_address(self):
    method test_correct_deployment (line 63) | def test_correct_deployment(self):
    method test_approval (line 71) | def test_approval(self):
    method test_create_order (line 84) | def test_create_order(self):
    method test_get_order_hash (line 108) | def test_get_order_hash(self):
    method test_sign_order (line 122) | def test_sign_order(self):
    method test_cancel_order (line 137) | def test_cancel_order(self):
    method test_fill_order (line 157) | def test_fill_order(self):
    method test_remaining_buy_amount_and_remaining_sell_amount (line 177) | def test_remaining_buy_amount_and_remaining_sell_amount(self):
    method test_past_fill (line 199) | def test_past_fill(self):
    method test_past_cancel (line 226) | def test_past_cancel(self):
    method test_should_have_printable_representation (line 248) | def test_should_have_printable_representation(self):
  class TestOrder (line 252) | class TestOrder:
    method test_should_be_comparable (line 253) | def test_should_be_comparable(self):
    method test_should_be_hashable (line 302) | def test_should_be_hashable(self):
    method test_parse_signed_json_order (line 323) | def test_parse_signed_json_order(self):
    method test_parse_unsigned_json_order (line 362) | def test_parse_unsigned_json_order(self):
    method test_serialize_order_to_json_without_fees (line 399) | def test_serialize_order_to_json_without_fees(self):
    method test_serialize_order_to_json (line 432) | def test_serialize_order_to_json(self):

FILE: utils/etherdelta-client/main.js
  function publishOrder (line 26) | function publishOrder() {
Condensed preview — 168 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,283K chars).
[
  {
    "path": ".github/workflows/tests.yaml",
    "chars": 747,
    "preview": "on:\n  # Trigger the workflow on push or pull request,\n  # but only for the main branch\n  push:\n    branches:\n      - mas"
  },
  {
    "path": ".gitignore",
    "chars": 158,
    "preview": ".idea\n*.iml\n\n__pycache__\n.cache\n.coverage\n.pytest_cache\n\n.DS_Store\n\nlogs/*.json.log\ntests/config/keys/UnlimitedChain/add"
  },
  {
    "path": ".python-version",
    "chars": 6,
    "preview": "3.6.6\n"
  },
  {
    "path": "COPYING",
    "chars": 34520,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "Makefile",
    "chars": 539,
    "preview": "help:           ## Show this help.\n\t@fgrep -h \"##\" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\\\$$//' | sed -e 's/##/"
  },
  {
    "path": "README.md",
    "chars": 15006,
    "preview": "# pymaker\n\nPython API for Maker contracts.\n\n![Build Status](https://github.com/makerdao/pymaker/actions/workflows/.githu"
  },
  {
    "path": "config/kovan-addresses.json",
    "chars": 12701,
    "preview": "{\n  \"CHANGELOG\": \"0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F\",\n  \"MULTICALL\": \"0xC6D81A2e375Eee15a20E6464b51c5FC6Bb949fd"
  },
  {
    "path": "config/mainnet-addresses.json",
    "chars": 19286,
    "preview": "{\n  \"CHANGELOG\": \"0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F\",\n  \"MULTICALL\": \"0x5e227AD1969Ea493B43F840cfF78d08a6fc1779"
  },
  {
    "path": "config/testnet-addresses.json",
    "chars": 4457,
    "preview": "{\n  \"DEPLOYER\": \"0x00a329c0648769A73afAc7F9381E08FB43dBEA72\",\n  \"MULTICALL\": \"0x492934308E98b590A626666B703A6dDf2120e85e"
  },
  {
    "path": "docker-compose.yml",
    "chars": 905,
    "preview": "version: \"3.2\"\nservices:\n  parity:\n    image: makerdao/testchain-pymaker:unit-testing-2.0.0\n    container_name: parity-p"
  },
  {
    "path": "docs/conf.py",
    "chars": 4641,
    "preview": "# -*- coding: utf-8 -*-\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note th"
  },
  {
    "path": "docs/index.rst",
    "chars": 2999,
    "preview": "pymaker API\n===========\n\nThe `pymaker` API exists to provide a simple way of interacting with Maker smart contracts.\n\nIt"
  },
  {
    "path": "pymaker/__init__.py",
    "chars": 41060,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/abi/Cat.abi",
    "chars": 4574,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t"
  },
  {
    "path": "pymaker/abi/Clipper.abi",
    "chars": 8176,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spotter_\",\"type\""
  },
  {
    "path": "pymaker/abi/ClipperCallee.abi",
    "chars": 310,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},"
  },
  {
    "path": "pymaker/abi/DSAuth.abi",
    "chars": 947,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"owner_\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMu"
  },
  {
    "path": "pymaker/abi/DSChief.abi",
    "chars": 8155,
    "preview": "[{\"inputs\":[{\"internalType\":\"contract DSToken\",\"name\":\"GOV\",\"type\":\"address\"},{\"internalType\":\"contract DSToken\",\"name\":"
  },
  {
    "path": "pymaker/abi/DSEthToken.abi",
    "chars": 2802,
    "preview": "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"type\":\"function\"},{"
  },
  {
    "path": "pymaker/abi/DSGuard.abi",
    "chars": 2254,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"owner_\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"type\":\""
  },
  {
    "path": "pymaker/abi/DSPause.abi",
    "chars": 2658,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"owner_\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMu"
  },
  {
    "path": "pymaker/abi/DSProxy.abi",
    "chars": 2207,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"owner_\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMu"
  },
  {
    "path": "pymaker/abi/DSProxyCache.abi",
    "chars": 365,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"write\",\"outputs\":[{\"name\":\"target\",\"type\":\"address"
  },
  {
    "path": "pymaker/abi/DSProxyFactory.abi",
    "chars": 927,
    "preview": "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"isProxy\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payabl"
  },
  {
    "path": "pymaker/abi/DSRoles.abi",
    "chars": 3033,
    "preview": "[{\"constant\":true,\"inputs\":[{\"name\":\"who\",\"type\":\"address\"}],\"name\":\"getUserRoles\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32"
  },
  {
    "path": "pymaker/abi/DSToken.abi",
    "chars": 5710,
    "preview": "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\""
  },
  {
    "path": "pymaker/abi/DSValue.abi",
    "chars": 1575,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"owner_\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"type\":\""
  },
  {
    "path": "pymaker/abi/DSVault.abi",
    "chars": 3024,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"token_\",\"type\":\"address\"}],\"name\":\"swap\",\"outputs\":[],\"payable\":false,\"type\":\"func"
  },
  {
    "path": "pymaker/abi/DaiJoin.abi",
    "chars": 2322,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dai_\",\"type\":\"ad"
  },
  {
    "path": "pymaker/abi/Dog.abi",
    "chars": 5482,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructo"
  },
  {
    "path": "pymaker/abi/DsrManager.abi",
    "chars": 2438,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pot_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"daiJoin_\",\"type\""
  },
  {
    "path": "pymaker/abi/DssCdpManager.abi",
    "chars": 6407,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t"
  },
  {
    "path": "pymaker/abi/DssProxyActionsDsr.abi",
    "chars": 1140,
    "preview": "[{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"apt\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\""
  },
  {
    "path": "pymaker/abi/ERC20Token.abi",
    "chars": 1563,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"guy\",\"type\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\""
  },
  {
    "path": "pymaker/abi/ESM.abi",
    "chars": 2084,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"gem_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"end_\",\"type\":\"ad"
  },
  {
    "path": "pymaker/abi/End.abi",
    "chars": 8304,
    "preview": "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Cage\",\"type\":\""
  },
  {
    "path": "pymaker/abi/EtherDelta.abi",
    "chars": 7765,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"tokenGet\",\"type\":\"address\"},{\"name\":\"amountGet\",\"type\":\"uint256\"},{\"name\":\"tokenGi"
  },
  {
    "path": "pymaker/abi/EtherToken.abi",
    "chars": 2129,
    "preview": "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"type\":\"function\"},{"
  },
  {
    "path": "pymaker/abi/Exchange.abi",
    "chars": 5983,
    "preview": "[{\"constant\":true,\"inputs\":[{\"name\":\"numerator\",\"type\":\"uint256\"},{\"name\":\"denominator\",\"type\":\"uint256\"},{\"name\":\"targe"
  },
  {
    "path": "pymaker/abi/ExchangeV2-ERC20Proxy.abi",
    "chars": 3064,
    "preview": "[\n\t\t\t{\n\t\t\t\t\"constant\": false,\n\t\t\t\t\"inputs\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"target\",\n\t\t\t\t\t\t\"type\": \"address\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\""
  },
  {
    "path": "pymaker/abi/ExchangeV2.abi",
    "chars": 35963,
    "preview": "[\n\t\t\t{\n\t\t\t\t\"constant\": true,\n\t\t\t\t\"inputs\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"\",\n\t\t\t\t\t\t\"type\": \"bytes32\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"name\": "
  },
  {
    "path": "pymaker/abi/Flapper.abi",
    "chars": 4654,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"gem_\",\"type\":\"ad"
  },
  {
    "path": "pymaker/abi/Flipper.abi",
    "chars": 5621,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"cat_\",\"type\":\"ad"
  },
  {
    "path": "pymaker/abi/Flopper.abi",
    "chars": 5063,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"gem_\",\"type\":\"ad"
  },
  {
    "path": "pymaker/abi/GemJoin.abi",
    "chars": 2712,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"ilk_\",\"type\":\"by"
  },
  {
    "path": "pymaker/abi/GemJoin5.abi",
    "chars": 2712,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"ilk_\",\"type\":\"by"
  },
  {
    "path": "pymaker/abi/Jug.abi",
    "chars": 3125,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t"
  },
  {
    "path": "pymaker/abi/MakerOtcSupportMethods.abi",
    "chars": 1536,
    "preview": "[{\"constant\":true,\"inputs\":[{\"name\":\"otc\",\"type\":\"address\"},{\"name\":\"payToken\",\"type\":\"address\"},{\"name\":\"buyToken\",\"typ"
  },
  {
    "path": "pymaker/abi/MatchingMarket.abi",
    "chars": 15378,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dustToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_dustLimit"
  },
  {
    "path": "pymaker/abi/OSM.abi",
    "chars": 4507,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t"
  },
  {
    "path": "pymaker/abi/Pit.abi",
    "chars": 2649,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"ilk\",\"type\":\"bytes32\"},{\"name\":\"what\",\"type\":\"bytes32\"},{\"name\":\"data\",\"type\":\"uin"
  },
  {
    "path": "pymaker/abi/Pot.abi",
    "chars": 3685,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t"
  },
  {
    "path": "pymaker/abi/ProxyRegistry.abi",
    "chars": 817,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"factory_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable"
  },
  {
    "path": "pymaker/abi/SaiTap.abi",
    "chars": 4609,
    "preview": "[{\"constant\":false,\"inputs\":[],\"name\":\"heal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"functio"
  },
  {
    "path": "pymaker/abi/SaiTop.abi",
    "chars": 3491,
    "preview": "[{\"constant\":true,\"inputs\":[],\"name\":\"sin\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"v"
  },
  {
    "path": "pymaker/abi/SaiTub.abi",
    "chars": 10513,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"join\",\"outputs\":[],\"payable\":false,\"stateMutabilit"
  },
  {
    "path": "pymaker/abi/SaiVox.abi",
    "chars": 2813,
    "preview": "[{\"constant\":false,\"inputs\":[],\"name\":\"prod\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"functio"
  },
  {
    "path": "pymaker/abi/SimpleMarket.abi",
    "chars": 6894,
    "preview": "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":true,\"in"
  },
  {
    "path": "pymaker/abi/Spotter.abi",
    "chars": 3357,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t"
  },
  {
    "path": "pymaker/abi/TokenFaucet.abi",
    "chars": 2426,
    "preview": "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":true,\"inputs\":[{\"indexed"
  },
  {
    "path": "pymaker/abi/TokenTransferProxy.abi",
    "chars": 1612,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"},{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"add"
  },
  {
    "path": "pymaker/abi/TxManager.abi",
    "chars": 1403,
    "preview": "[{\"constant\":false,\"inputs\":[{\"name\":\"owner_\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMu"
  },
  {
    "path": "pymaker/abi/Vat.abi",
    "chars": 7743,
    "preview": "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":true,\"inputs\":[{\"indexed"
  },
  {
    "path": "pymaker/abi/Vow.abi",
    "chars": 5049,
    "preview": "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vat_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"flapper_\",\"type\""
  },
  {
    "path": "pymaker/abi/ZRXToken.abi",
    "chars": 1921,
    "preview": "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"type\":\"function\"},{"
  },
  {
    "path": "pymaker/abi/diff-abi.sh",
    "chars": 153,
    "preview": "#!/bin/bash\n\n# This script is useful when updating ABIs as newer contracts are released.\nvimdiff <(git show HEAD:pymaker"
  },
  {
    "path": "pymaker/approval.py",
    "chars": 4471,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/auctions.py",
    "chars": 34263,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2018-2019 reverendus, bargst, EdNoepel\n#\n# This program"
  },
  {
    "path": "pymaker/auth.py",
    "chars": 3951,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/cdpmanager.py",
    "chars": 3485,
    "preview": "\n# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2020 ith-harvey\n#\n# This program is free software"
  },
  {
    "path": "pymaker/collateral.py",
    "chars": 2753,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019-2021 EdNoepel\n#\n# This program is free software: y"
  },
  {
    "path": "pymaker/deployment.py",
    "chars": 17720,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus, bargst\n#\n# This program is free s"
  },
  {
    "path": "pymaker/dsr.py",
    "chars": 4235,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C)2019 grandizzy\n#\n# This program is free software: you ca"
  },
  {
    "path": "pymaker/dsrmanager.py",
    "chars": 3819,
    "preview": "\n# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 Maker Ecosystem Growth Holdings, INC\n#\n# This pro"
  },
  {
    "path": "pymaker/dss.py",
    "chars": 37197,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2018-2021 bargst, EdNoepel\n#\n# This program is free sof"
  },
  {
    "path": "pymaker/etherdelta.py",
    "chars": 27307,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/feed.py",
    "chars": 5535,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/gas.py",
    "chars": 8673,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/governance.py",
    "chars": 9908,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "pymaker/ilk.py",
    "chars": 3057,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019-2021 EdNoepel\n#\n# This program is free software: y"
  },
  {
    "path": "pymaker/join.py",
    "chars": 4188,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019-2021 EdNoepel\n#\n# This program is free software: y"
  },
  {
    "path": "pymaker/keys.py",
    "chars": 2969,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2018 reverendus\n#\n# This program is free software: you "
  },
  {
    "path": "pymaker/lifecycle.py",
    "chars": 21353,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/logging.py",
    "chars": 2545,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "pymaker/model.py",
    "chars": 2822,
    "preview": "# This file is part of Maker Keeper Framework.\n# \n# Copyright (C) 2017-2020 mitakash, MikeHathaway\n#\n# This program is f"
  },
  {
    "path": "pymaker/numeric.py",
    "chars": 14935,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n# Copyright (C) 2018 bargst\n#\n# Th"
  },
  {
    "path": "pymaker/oasis.py",
    "chars": 31378,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/oracles.py",
    "chars": 2670,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019 grandizzy\n#\n# This program is free software: you c"
  },
  {
    "path": "pymaker/proxy.py",
    "chars": 11257,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2018,2019 bargst\n#\n# This program is free software: you"
  },
  {
    "path": "pymaker/reloadable_config.py",
    "chars": 4637,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 MikeHathaway\n#\n# This is proprietary (closed sourc"
  },
  {
    "path": "pymaker/sai.py",
    "chars": 33281,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/shutdown.py",
    "chars": 8204,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "pymaker/sign.py",
    "chars": 2753,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/tightly_packed.py",
    "chars": 1121,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/token.py",
    "chars": 14969,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/transactional.py",
    "chars": 4493,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/util.py",
    "chars": 5808,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/vault.py",
    "chars": 2662,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/zrx.py",
    "chars": 27376,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "pymaker/zrxv2.py",
    "chars": 31726,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "requirements-dev.txt",
    "chars": 203,
    "preview": "attrs == 19.1.0\ncodecov == 2.0.9\nmock == 2.0.0\npytest == 3.3.0\npytest-asyncio == 0.9.0\npytest-cov == 2.5.1\npytest-mock ="
  },
  {
    "path": "requirements.txt",
    "chars": 89,
    "preview": "pytz == 2017.3\nweb3 == 5.12.0\nrequests == 2.22.0\neth-keys<0.3.0,>=0.2.1\njsonnet == 0.9.5\n"
  },
  {
    "path": "setup.py",
    "chars": 1930,
    "preview": "\"\"\"A setuptools based setup module.\n\nSee:\nhttps://packaging.python.org/guides/distributing-packages-using-setuptools/\nht"
  },
  {
    "path": "test-dss.sh",
    "chars": 568,
    "preview": "#!/bin/bash\n\n# Pull the docker image\ndocker pull makerdao/testchain-pymaker:unit-testing\n\n# Remove existing container if"
  },
  {
    "path": "test.sh",
    "chars": 436,
    "preview": "#!/bin/bash\n\n# Pull the docker image\ndocker pull makerdao/testchain-pymaker:unit-testing\n\n# Remove existing container if"
  },
  {
    "path": "tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/abi/DaiMock.abi",
    "chars": 1529,
    "preview": "[{\"constant\":true,\"inputs\":[],\"name\":\"vat\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"v"
  },
  {
    "path": "tests/abi/DaiMock.sol",
    "chars": 1513,
    "preview": "pragma solidity ^0.4.24;\n\n// Fusion between a DaiJoin and a DaiMove\n\ncontract GemLike {\n    function transferFrom(addres"
  },
  {
    "path": "tests/abi/GemMock.abi",
    "chars": 6407,
    "preview": "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\""
  },
  {
    "path": "tests/abi/GemMock.sol",
    "chars": 536,
    "preview": "pragma solidity ^0.4.24;\n\nimport \"ds-token/token.sol\";\n\ncontract GemMock is DSToken('') {\n\n    constructor(bytes32 symbo"
  },
  {
    "path": "tests/abi/OasisMockPriceOracle.abi",
    "chars": 579,
    "preview": "[{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"t"
  },
  {
    "path": "tests/abi/OasisMockPriceOracle.sol",
    "chars": 277,
    "preview": "pragma solidity ^0.5.12;\n\ncontract OasisMockPriceOracle {\n    uint256 price;\n    function setPrice(address, uint256 _pri"
  },
  {
    "path": "tests/accounts/0_0x9596c16d7bf9323265c2f2e22f43e6c80eb3d943.json",
    "chars": 491,
    "preview": "{\"version\":3,\"id\":\"375c1ad3-b203-4e32-b32a-dd5cad819a4c\",\"address\":\"9596c16d7bf9323265c2f2e22f43e6c80eb3d943\",\"crypto\":{"
  },
  {
    "path": "tests/accounts/1_0xe415482ca06eeb684ad3f758c2129fca4b1eb1f4.json",
    "chars": 491,
    "preview": "{\"version\":3,\"id\":\"d2275fb9-533f-4c63-b970-9767bb45d38d\",\"address\":\"e415482ca06eeb684ad3f758c2129fca4b1eb1f4\",\"crypto\":{"
  },
  {
    "path": "tests/accounts/2_0x270b0e8d873e858abd698a000b0da0b94e21d84c.json",
    "chars": 491,
    "preview": "{\"version\":3,\"id\":\"3088cf66-27a4-4da4-a5de-bb03fdfc1751\",\"address\":\"270b0e8d873e858abd698a000b0da0b94e21d84c\",\"crypto\":{"
  },
  {
    "path": "tests/accounts/3_0x812e87be5d4198fca55cb52fa60cb46620617474.json",
    "chars": 491,
    "preview": "{\"version\":3,\"id\":\"c0870e2f-9f3b-48b6-a670-cd056d3c6931\",\"address\":\"812e87be5d4198fca55cb52fa60cb46620617474\",\"crypto\":{"
  },
  {
    "path": "tests/accounts/4_0x13314e21cd6d343ceb857073f3f6d9368919d1ef.json",
    "chars": 491,
    "preview": "{\"version\":3,\"id\":\"f9455bbb-482b-46f7-9e29-503838c386be\",\"address\":\"13314e21cd6d343ceb857073f3f6d9368919d1ef\",\"crypto\":{"
  },
  {
    "path": "tests/accounts/5_0x176087fea5c41fc370fabbd850521bc4451690ca.json",
    "chars": 491,
    "preview": "{\"version\":3,\"id\":\"aaf50a37-d4d1-41ef-ad91-ac5e20a0f5b4\",\"address\":\"176087fea5c41fc370fabbd850521bc4451690ca\",\"crypto\":{"
  },
  {
    "path": "tests/accounts/pass",
    "chars": 8,
    "preview": "12345678"
  },
  {
    "path": "tests/config/keys/UnlimitedChain/key.json",
    "chars": 657,
    "preview": "{\"id\":\"032b64c7-38c6-dfb4-714a-25eacd2daecc\",\"version\":3,\"crypto\":{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"38f902a7"
  },
  {
    "path": "tests/config/keys/UnlimitedChain/key1.json",
    "chars": 520,
    "preview": "{\"id\":\"09068027-f04d-f8fb-79d9-9df6f03ac604\",\"version\":3,\"crypto\":{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"4ac591b3"
  },
  {
    "path": "tests/config/keys/UnlimitedChain/key2.json",
    "chars": 520,
    "preview": "{\"id\":\"6e7c69aa-e8d3-e381-ed85-36a08df7cfbe\",\"version\":3,\"crypto\":{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"e19eee7d"
  },
  {
    "path": "tests/config/keys/UnlimitedChain/key3.json",
    "chars": 520,
    "preview": "{\"id\":\"ecf98a52-7a41-0b18-a39a-e57ddc7a41d9\",\"version\":3,\"crypto\":{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"c40c8be2"
  },
  {
    "path": "tests/config/keys/UnlimitedChain/key4.json",
    "chars": 520,
    "preview": "{\"id\":\"d2bed4ab-c313-7430-be81-8a0d04bfc9aa\",\"version\":3,\"crypto\":{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"b7b2722e"
  },
  {
    "path": "tests/config/parity-dev-constantinopole.json",
    "chars": 24485,
    "preview": "{\n  \"name\": \"UnlimitedChain\",\n  \"engine\": {\n    \"instantSeal\": {\n      \"params\": {}\n    }\n  },\n  \"params\": {\n    \"gasLim"
  },
  {
    "path": "tests/conftest.py",
    "chars": 3985,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2019 reverendus, EdNoepel\n#\n# This program is free"
  },
  {
    "path": "tests/dss_token.py",
    "chars": 2619,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/helpers.py",
    "chars": 1990,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/manual_test_async_tx.py",
    "chars": 3989,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "tests/manual_test_cdpmanager.py",
    "chars": 2548,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 ith-harvey\n#\n# This program is free software: you "
  },
  {
    "path": "tests/manual_test_dsr.py",
    "chars": 2299,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019 grandizzy\n#\n# This program is free software: you c"
  },
  {
    "path": "tests/manual_test_goerli.py",
    "chars": 3041,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020-2021 EdNoepel\n#\n# This program is free software: y"
  },
  {
    "path": "tests/manual_test_mcd.py",
    "chars": 4117,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019-2020 EdNoepel\n#\n# This program is free software: y"
  },
  {
    "path": "tests/manual_test_node.py",
    "chars": 3489,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "tests/manual_test_tx_recovery.py",
    "chars": 3333,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "tests/manual_test_zrxv2.py",
    "chars": 2390,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_approval.py",
    "chars": 4801,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_auctions.py",
    "chars": 31880,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2018-2019 reverendus, bargst, EdNoepel\n#\n# This program"
  },
  {
    "path": "tests/test_auth.py",
    "chars": 3919,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_cdpmanager.py",
    "chars": 1726,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "tests/test_dsrmanager.py",
    "chars": 4574,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 Maker Ecosystem Growth Holdings, INC\n#\n# This prog"
  },
  {
    "path": "tests/test_dss.py",
    "chars": 30719,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2018-2019 bargst, EdNoepel\n#\n# This program is free sof"
  },
  {
    "path": "tests/test_etherdelta.py",
    "chars": 9608,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_feed.py",
    "chars": 3566,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_gas.py",
    "chars": 9351,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_general.py",
    "chars": 15390,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_general2.py",
    "chars": 13004,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_governance.py",
    "chars": 4816,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "tests/test_keys.py",
    "chars": 5052,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_lifecycle.py",
    "chars": 12768,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_model.py",
    "chars": 1927,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "tests/test_numeric.py",
    "chars": 28239,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_oasis.py",
    "chars": 31684,
    "preview": "# This file is part of Maker Keeper Framework.\n\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software"
  },
  {
    "path": "tests/test_proxy.py",
    "chars": 5684,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2018,2019 bargst\n#\n# This program is free software: you"
  },
  {
    "path": "tests/test_reloadable_config.py",
    "chars": 4233,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2020 MikeHathaway\n#\n# This program is free software: yo"
  },
  {
    "path": "tests/test_sai.py",
    "chars": 20762,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_savings.py",
    "chars": 3528,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019 grandizzy\n#\n# This program is free software: you c"
  },
  {
    "path": "tests/test_shutdown.py",
    "chars": 7823,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2019 EdNoepel\n#\n# This program is free software: you ca"
  },
  {
    "path": "tests/test_sign.py",
    "chars": 2159,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_token.py",
    "chars": 10731,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_transactional.py",
    "chars": 4660,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_util.py",
    "chars": 9714,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_vault.py",
    "chars": 1770,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_zrx.py",
    "chars": 24514,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "tests/test_zrxv2.py",
    "chars": 25080,
    "preview": "# This file is part of Maker Keeper Framework.\n#\n# Copyright (C) 2017-2018 reverendus\n#\n# This program is free software:"
  },
  {
    "path": "utils/etherdelta-client/.gitignore",
    "chars": 13,
    "preview": "node_modules/"
  },
  {
    "path": "utils/etherdelta-client/main.js",
    "chars": 1943,
    "preview": "/*!\n * This file is part of Maker Keeper Framework.\n *\n * Copyright (C) 2017-2018 reverendus\n *\n * This program is free "
  },
  {
    "path": "utils/etherdelta-client/package.json",
    "chars": 297,
    "preview": "{\n  \"name\": \"etherdelta-client\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"main.js\",\n  \"scripts\": {\n    \"tes"
  }
]

About this extraction

This page contains the full source code of the makerdao/pymaker GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 168 files (1.1 MB), approximately 311.5k tokens, and a symbol index with 1735 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!