ETH Price: $2,136.33 (+7.71%)

Transaction Decoder

Block:
13273521 at Sep-22-2021 04:48:20 AM +UTC
Transaction Fee:
0.011322531 ETH $24.19
Gas Used:
190,615 Gas / 59.4 Gwei

Emitted Events:

298 Dai.Approval( src=[Receiver] 0xd791f0b01de84f6d5000f8c62088b8bc8114005e, guy=DaiJoin, wad=3412908644580084935582 )
299 Vat.0xbb35783b00000000000000000000000000000000000000000000000000000000( 0xbb35783b00000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000009759a6ac90977b93b58547b4a71c78317f391a28, 0x0000000000000000000000003f439420cb9574e4e2f02c58ce1ba5a4b545d6af, 0x00000000000000000000000255d01dd6f0ebf288107aac470d19868f30000000, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, bb35783b0000000000000000000000009759a6ac90977b93b58547b4a71c7831, 7f391a280000000000000000000000003f439420cb9574e4e2f02c58ce1ba5a4, b545d6af00000000000000000000000255d01dd6f0ebf288107aac470d19868f, 3000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
300 Dai.Transfer( src=[Receiver] 0xd791f0b01de84f6d5000f8c62088b8bc8114005e, dst=0x0000000000000000000000000000000000000000, wad=3412908644580084935582 )
301 DaiJoin.0x3b4da69f00000000000000000000000000000000000000000000000000000000( 0x3b4da69f00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000d791f0b01de84f6d5000f8c62088b8bc8114005e, 0x0000000000000000000000003f439420cb9574e4e2f02c58ce1ba5a4b545d6af, 0x0000000000000000000000000000000000000000000000b9039f39e16fdbeb9e, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, 3b4da69f0000000000000000000000003f439420cb9574e4e2f02c58ce1ba5a4, b545d6af0000000000000000000000000000000000000000000000b9039f39e1, 6fdbeb9e00000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
302 Vat.0x7608870300000000000000000000000000000000000000000000000000000000( 0x7608870300000000000000000000000000000000000000000000000000000000, 0x4c494e4b2d410000000000000000000000000000000000000000000000000000, 0x0000000000000000000000003f439420cb9574e4e2f02c58ce1ba5a4b545d6af, 0x0000000000000000000000003f439420cb9574e4e2f02c58ce1ba5a4b545d6af, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, 760887034c494e4b2d4100000000000000000000000000000000000000000000, 000000000000000000000000000000003f439420cb9574e4e2f02c58ce1ba5a4, b545d6af0000000000000000000000003f439420cb9574e4e2f02c58ce1ba5a4, b545d6af0000000000000000000000003f439420cb9574e4e2f02c58ce1ba5a4, b545d6af00000000000000000000000000000000000000000000000000000000, 00000000ffffffffffffffffffffffffffffffffffffffffffffff4bc3bf0d9b, e9743dfa00000000000000000000000000000000000000000000000000000000 )
303 DssCdpManager.0x45e6bdcd00000000000000000000000000000000000000000000000000000000( 0x45e6bdcd00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000d791f0b01de84f6d5000f8c62088b8bc8114005e, 0x0000000000000000000000000000000000000000000000000000000000005849, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, 45e6bdcd00000000000000000000000000000000000000000000000000000000, 0000584900000000000000000000000000000000000000000000000000000000, 00000000ffffffffffffffffffffffffffffffffffffffffffffff4bc3bf0d9b, e9743dfa00000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
304 0xd791f0b01de84f6d5000f8c62088b8bc8114005e.0xf6d9b29bbf2ae698de33670961ec53f895af65801d2cdaced431cc6129865347( 0xf6d9b29bbf2ae698de33670961ec53f895af65801d2cdaced431cc6129865347, 0x00000000000000000000000003d70891b8994feb6cca7022b25c32be92ee3725, 0x0000000000000000000000004bc8804c1377bdd1345ee20d9b9a8742f138a98e, 0000000000000000000000000000000000000000000000000000000000000000, 00000000000000000000000000000000000000000000000000000000000000a0, 0000000000000000000000000000000000000000000000000000000000000120, 0000000000000000000000000000000000000000000000000000000000000160, 0000000000000000000000000000000000000000000000000000000000000200, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000020, 000000000000000000000000000000000000000000000000000000000000000a, 4d414b455244414f2d4100000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000004049db23c605b197f764072569b8db2464653ef6, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000020, 0000000000000000000000000000000000000000000000000000000000000033, 4c6f675061796261636b2875696e743235362c627974657333322c75696e7432, 35362c75696e743235362c75696e743235362900000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000a0, 0000000000000000000000000000000000000000000000000000000000005849, 4c494e4b2d410000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000b9039f39e16fdbeb9e, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
(2Miners: PPLNS)
3,448.324639462728504547 Eth3,448.324871928863594987 Eth0.00023246613509044
0x35D1b3F3...259A0492B
(Sky: MCD Vat)
0x4BC8804C...2f138a98E
0.228057691393173422 Eth
Nonce: 1031
0.216735160393173422 Eth
Nonce: 1032
0.011322531
0x6B175474...495271d0F

Execution Trace

0xd791f0b01de84f6d5000f8c62088b8bc8114005e.9304c934( )
  • InstaAccountV2.9304c934( )
    • InstaImplementations.getImplementation( _sig=System.Byte[] ) => ( 0x8a3462A50e1a9Fe8c9e7d9023CAcbD9a98D90021 )
    • InstaImplementationM1.cast( _targetNames=[MAKERDAO-A], _datas=[1eDaNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC5A5854W/b654AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA], _origin=0x03d70891b8994feB6ccA7022B25c32be92ee3725 ) => ( 0000000000000000000000000000000000000000000000000000000000000000 )
      • InstaConnectorsV2.isConnectors( _connectorNames=[MAKERDAO-A] ) => ( isOk=True, _connectors=[0x4049db23C605b197f764072569B8DB2464653Ef6] )
      • ConnectV2MakerDAO.payback( vault=22601, amt=3412908644580084935582, getId=0, setId=0 ) => ( _eventName=LogPayback(uint256,bytes32,uint256,uint256,uint256), _eventParam=0x00000000000000000000000000000000000000000000000000000000000058494C494E4B2D4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9039F39E16FDBEB9E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 )
        • DssCdpManager.ilks( 22601 ) => ( 4C494E4B2D410000000000000000000000000000000000000000000000000000 )
        • DssCdpManager.urns( 22601 ) => ( 0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af )
        • DssCdpManager.STATICCALL( )
        • Vat.ilks( 4C494E4B2D410000000000000000000000000000000000000000000000000000 ) => ( Art=40444207002999374227892279, rate=1026514121190944233302946331, spot=13308078787878787878787878787, line=50149920409221199976669370549250165354962529192798087, dust=10000000000000000000000000000000000000000000000000 )
        • Vat.urns( 4C494E4B2D410000000000000000000000000000000000000000000000000000, 0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af ) => ( ink=3750608128511588986947, art=38953324328610795319704 )
        • Vat.dai( 0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af ) => ( 254701806650749539461997589 )
        • DaiJoin.CALL( )
        • Dai.approve( usr=0x9759A6Ac90977b93B58547b4A71c78317f391A28, wad=3412908644580084935582 ) => ( True )
        • DaiJoin.join( usr=0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af, wad=3412908644580084935582 )
          • Vat.move( src=0x9759A6Ac90977b93B58547b4A71c78317f391A28, dst=0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af, rad=3412908644580084935582000000000000000000000000000 )
          • Dai.burn( usr=0xD791f0b01DE84f6D5000f8c62088B8bc8114005e, wad=3412908644580084935582 )
          • Vat.dai( 0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af ) => ( 3412908644580084935582254701806650749539461997589 )
          • Vat.ilks( 4C494E4B2D410000000000000000000000000000000000000000000000000000 ) => ( Art=40444207002999374227892279, rate=1026514121190944233302946331, spot=13308078787878787878787878787, line=50149920409221199976669370549250165354962529192798087, dust=10000000000000000000000000000000000000000000000000 )
          • Vat.urns( 4C494E4B2D410000000000000000000000000000000000000000000000000000, 0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af ) => ( ink=3750608128511588986947, art=38953324328610795319704 )
          • DssCdpManager.frob( cdp=22601, dink=0, dart=-3324755669820193358342 )
            • Vat.frob( i=4C494E4B2D410000000000000000000000000000000000000000000000000000, u=0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af, v=0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af, w=0x3F439420CB9574E4e2f02C58cE1Ba5A4B545d6af, dink=0, dart=-3324755669820193358342 )
              File 1 of 9: Dai
              // hevm: flattened sources of /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/dai.sol
              pragma solidity =0.5.12;
              
              ////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/lib.sol
              // This program is free software: you can redistribute it and/or modify
              // it under the terms of the GNU General Public License as published by
              // the Free Software Foundation, either version 3 of the License, or
              // (at your option) any later version.
              
              // This program is distributed in the hope that it will be useful,
              // but WITHOUT ANY WARRANTY; without even the implied warranty of
              // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
              // GNU General Public License for more details.
              
              // You should have received a copy of the GNU General Public License
              // along with this program.  If not, see <http://www.gnu.org/licenses/>.
              
              /* pragma solidity 0.5.12; */
              
              contract LibNote {
                  event LogNote(
                      bytes4   indexed  sig,
                      address  indexed  usr,
                      bytes32  indexed  arg1,
                      bytes32  indexed  arg2,
                      bytes             data
                  ) anonymous;
              
                  modifier note {
                      _;
                      assembly {
                          // log an 'anonymous' event with a constant 6 words of calldata
                          // and four indexed topics: selector, caller, arg1 and arg2
                          let mark := msize                         // end of memory ensures zero
                          mstore(0x40, add(mark, 288))              // update free memory pointer
                          mstore(mark, 0x20)                        // bytes type data offset
                          mstore(add(mark, 0x20), 224)              // bytes size (padded)
                          calldatacopy(add(mark, 0x40), 0, 224)     // bytes payload
                          log4(mark, 288,                           // calldata
                               shl(224, shr(224, calldataload(0))), // msg.sig
                               caller,                              // msg.sender
                               calldataload(4),                     // arg1
                               calldataload(36)                     // arg2
                              )
                      }
                  }
              }
              
              ////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/dai.sol
              // Copyright (C) 2017, 2018, 2019 dbrock, rain, mrchico
              
              // 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 <https://www.gnu.org/licenses/>.
              
              /* pragma solidity 0.5.12; */
              
              /* import "./lib.sol"; */
              
              contract Dai is LibNote {
                  // --- Auth ---
                  mapping (address => uint) public wards;
                  function rely(address guy) external note auth { wards[guy] = 1; }
                  function deny(address guy) external note auth { wards[guy] = 0; }
                  modifier auth {
                      require(wards[msg.sender] == 1, "Dai/not-authorized");
                      _;
                  }
              
                  // --- ERC20 Data ---
                  string  public constant name     = "Dai Stablecoin";
                  string  public constant symbol   = "DAI";
                  string  public constant version  = "1";
                  uint8   public constant decimals = 18;
                  uint256 public totalSupply;
              
                  mapping (address => uint)                      public balanceOf;
                  mapping (address => mapping (address => uint)) public allowance;
                  mapping (address => uint)                      public nonces;
              
                  event Approval(address indexed src, address indexed guy, uint wad);
                  event Transfer(address indexed src, address indexed dst, uint wad);
              
                  // --- Math ---
                  function add(uint x, uint y) internal pure returns (uint z) {
                      require((z = x + y) >= x);
                  }
                  function sub(uint x, uint y) internal pure returns (uint z) {
                      require((z = x - y) <= x);
                  }
              
                  // --- EIP712 niceties ---
                  bytes32 public DOMAIN_SEPARATOR;
                  // bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)");
                  bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;
              
                  constructor(uint256 chainId_) public {
                      wards[msg.sender] = 1;
                      DOMAIN_SEPARATOR = keccak256(abi.encode(
                          keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                          keccak256(bytes(name)),
                          keccak256(bytes(version)),
                          chainId_,
                          address(this)
                      ));
                  }
              
                  // --- Token ---
                  function transfer(address dst, uint wad) external returns (bool) {
                      return transferFrom(msg.sender, dst, wad);
                  }
                  function transferFrom(address src, address dst, uint wad)
                      public returns (bool)
                  {
                      require(balanceOf[src] >= wad, "Dai/insufficient-balance");
                      if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
                          require(allowance[src][msg.sender] >= wad, "Dai/insufficient-allowance");
                          allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
                      }
                      balanceOf[src] = sub(balanceOf[src], wad);
                      balanceOf[dst] = add(balanceOf[dst], wad);
                      emit Transfer(src, dst, wad);
                      return true;
                  }
                  function mint(address usr, uint wad) external auth {
                      balanceOf[usr] = add(balanceOf[usr], wad);
                      totalSupply    = add(totalSupply, wad);
                      emit Transfer(address(0), usr, wad);
                  }
                  function burn(address usr, uint wad) external {
                      require(balanceOf[usr] >= wad, "Dai/insufficient-balance");
                      if (usr != msg.sender && allowance[usr][msg.sender] != uint(-1)) {
                          require(allowance[usr][msg.sender] >= wad, "Dai/insufficient-allowance");
                          allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad);
                      }
                      balanceOf[usr] = sub(balanceOf[usr], wad);
                      totalSupply    = sub(totalSupply, wad);
                      emit Transfer(usr, address(0), wad);
                  }
                  function approve(address usr, uint wad) external returns (bool) {
                      allowance[msg.sender][usr] = wad;
                      emit Approval(msg.sender, usr, wad);
                      return true;
                  }
              
                  // --- Alias ---
                  function push(address usr, uint wad) external {
                      transferFrom(msg.sender, usr, wad);
                  }
                  function pull(address usr, uint wad) external {
                      transferFrom(usr, msg.sender, wad);
                  }
                  function move(address src, address dst, uint wad) external {
                      transferFrom(src, dst, wad);
                  }
              
                  // --- Approve by signature ---
                  function permit(address holder, address spender, uint256 nonce, uint256 expiry,
                                  bool allowed, uint8 v, bytes32 r, bytes32 s) external
                  {
                      bytes32 digest =
                          keccak256(abi.encodePacked(
                              "\x19\x01",
                              DOMAIN_SEPARATOR,
                              keccak256(abi.encode(PERMIT_TYPEHASH,
                                                   holder,
                                                   spender,
                                                   nonce,
                                                   expiry,
                                                   allowed))
                      ));
              
                      require(holder != address(0), "Dai/invalid-address-0");
                      require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit");
                      require(expiry == 0 || now <= expiry, "Dai/permit-expired");
                      require(nonce == nonces[holder]++, "Dai/invalid-nonce");
                      uint wad = allowed ? uint(-1) : 0;
                      allowance[holder][spender] = wad;
                      emit Approval(holder, spender, wad);
                  }
              }

              File 2 of 9: Vat
              // hevm: flattened sources of /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/vat.sol
              pragma solidity =0.5.12;
              
              ////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/vat.sol
              /// vat.sol -- Dai CDP database
              
              // Copyright (C) 2018 Rain <rainbreak@riseup.net>
              //
              // 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 <https://www.gnu.org/licenses/>.
              
              /* pragma solidity 0.5.12; */
              
              contract Vat {
                  // --- Auth ---
                  mapping (address => uint) public wards;
                  function rely(address usr) external note auth { require(live == 1, "Vat/not-live"); wards[usr] = 1; }
                  function deny(address usr) external note auth { require(live == 1, "Vat/not-live"); wards[usr] = 0; }
                  modifier auth {
                      require(wards[msg.sender] == 1, "Vat/not-authorized");
                      _;
                  }
              
                  mapping(address => mapping (address => uint)) public can;
                  function hope(address usr) external note { can[msg.sender][usr] = 1; }
                  function nope(address usr) external note { can[msg.sender][usr] = 0; }
                  function wish(address bit, address usr) internal view returns (bool) {
                      return either(bit == usr, can[bit][usr] == 1);
                  }
              
                  // --- Data ---
                  struct Ilk {
                      uint256 Art;   // Total Normalised Debt     [wad]
                      uint256 rate;  // Accumulated Rates         [ray]
                      uint256 spot;  // Price with Safety Margin  [ray]
                      uint256 line;  // Debt Ceiling              [rad]
                      uint256 dust;  // Urn Debt Floor            [rad]
                  }
                  struct Urn {
                      uint256 ink;   // Locked Collateral  [wad]
                      uint256 art;   // Normalised Debt    [wad]
                  }
              
                  mapping (bytes32 => Ilk)                       public ilks;
                  mapping (bytes32 => mapping (address => Urn )) public urns;
                  mapping (bytes32 => mapping (address => uint)) public gem;  // [wad]
                  mapping (address => uint256)                   public dai;  // [rad]
                  mapping (address => uint256)                   public sin;  // [rad]
              
                  uint256 public debt;  // Total Dai Issued    [rad]
                  uint256 public vice;  // Total Unbacked Dai  [rad]
                  uint256 public Line;  // Total Debt Ceiling  [rad]
                  uint256 public live;  // Access Flag
              
                  // --- Logs ---
                  event LogNote(
                      bytes4   indexed  sig,
                      bytes32  indexed  arg1,
                      bytes32  indexed  arg2,
                      bytes32  indexed  arg3,
                      bytes             data
                  ) anonymous;
              
                  modifier note {
                      _;
                      assembly {
                          // log an 'anonymous' event with a constant 6 words of calldata
                          // and four indexed topics: the selector and the first three args
                          let mark := msize                         // end of memory ensures zero
                          mstore(0x40, add(mark, 288))              // update free memory pointer
                          mstore(mark, 0x20)                        // bytes type data offset
                          mstore(add(mark, 0x20), 224)              // bytes size (padded)
                          calldatacopy(add(mark, 0x40), 0, 224)     // bytes payload
                          log4(mark, 288,                           // calldata
                               shl(224, shr(224, calldataload(0))), // msg.sig
                               calldataload(4),                     // arg1
                               calldataload(36),                    // arg2
                               calldataload(68)                     // arg3
                              )
                      }
                  }
              
                  // --- Init ---
                  constructor() public {
                      wards[msg.sender] = 1;
                      live = 1;
                  }
              
                  // --- Math ---
                  function add(uint x, int y) internal pure returns (uint z) {
                      z = x + uint(y);
                      require(y >= 0 || z <= x);
                      require(y <= 0 || z >= x);
                  }
                  function sub(uint x, int y) internal pure returns (uint z) {
                      z = x - uint(y);
                      require(y <= 0 || z <= x);
                      require(y >= 0 || z >= x);
                  }
                  function mul(uint x, int y) internal pure returns (int z) {
                      z = int(x) * y;
                      require(int(x) >= 0);
                      require(y == 0 || z / y == int(x));
                  }
                  function add(uint x, uint y) internal pure returns (uint z) {
                      require((z = x + y) >= x);
                  }
                  function sub(uint x, uint y) internal pure returns (uint z) {
                      require((z = x - y) <= x);
                  }
                  function mul(uint x, uint y) internal pure returns (uint z) {
                      require(y == 0 || (z = x * y) / y == x);
                  }
              
                  // --- Administration ---
                  function init(bytes32 ilk) external note auth {
                      require(ilks[ilk].rate == 0, "Vat/ilk-already-init");
                      ilks[ilk].rate = 10 ** 27;
                  }
                  function file(bytes32 what, uint data) external note auth {
                      require(live == 1, "Vat/not-live");
                      if (what == "Line") Line = data;
                      else revert("Vat/file-unrecognized-param");
                  }
                  function file(bytes32 ilk, bytes32 what, uint data) external note auth {
                      require(live == 1, "Vat/not-live");
                      if (what == "spot") ilks[ilk].spot = data;
                      else if (what == "line") ilks[ilk].line = data;
                      else if (what == "dust") ilks[ilk].dust = data;
                      else revert("Vat/file-unrecognized-param");
                  }
                  function cage() external note auth {
                      live = 0;
                  }
              
                  // --- Fungibility ---
                  function slip(bytes32 ilk, address usr, int256 wad) external note auth {
                      gem[ilk][usr] = add(gem[ilk][usr], wad);
                  }
                  function flux(bytes32 ilk, address src, address dst, uint256 wad) external note {
                      require(wish(src, msg.sender), "Vat/not-allowed");
                      gem[ilk][src] = sub(gem[ilk][src], wad);
                      gem[ilk][dst] = add(gem[ilk][dst], wad);
                  }
                  function move(address src, address dst, uint256 rad) external note {
                      require(wish(src, msg.sender), "Vat/not-allowed");
                      dai[src] = sub(dai[src], rad);
                      dai[dst] = add(dai[dst], rad);
                  }
              
                  function either(bool x, bool y) internal pure returns (bool z) {
                      assembly{ z := or(x, y)}
                  }
                  function both(bool x, bool y) internal pure returns (bool z) {
                      assembly{ z := and(x, y)}
                  }
              
                  // --- CDP Manipulation ---
                  function frob(bytes32 i, address u, address v, address w, int dink, int dart) external note {
                      // system is live
                      require(live == 1, "Vat/not-live");
              
                      Urn memory urn = urns[i][u];
                      Ilk memory ilk = ilks[i];
                      // ilk has been initialised
                      require(ilk.rate != 0, "Vat/ilk-not-init");
              
                      urn.ink = add(urn.ink, dink);
                      urn.art = add(urn.art, dart);
                      ilk.Art = add(ilk.Art, dart);
              
                      int dtab = mul(ilk.rate, dart);
                      uint tab = mul(ilk.rate, urn.art);
                      debt     = add(debt, dtab);
              
                      // either debt has decreased, or debt ceilings are not exceeded
                      require(either(dart <= 0, both(mul(ilk.Art, ilk.rate) <= ilk.line, debt <= Line)), "Vat/ceiling-exceeded");
                      // urn is either less risky than before, or it is safe
                      require(either(both(dart <= 0, dink >= 0), tab <= mul(urn.ink, ilk.spot)), "Vat/not-safe");
              
                      // urn is either more safe, or the owner consents
                      require(either(both(dart <= 0, dink >= 0), wish(u, msg.sender)), "Vat/not-allowed-u");
                      // collateral src consents
                      require(either(dink <= 0, wish(v, msg.sender)), "Vat/not-allowed-v");
                      // debt dst consents
                      require(either(dart >= 0, wish(w, msg.sender)), "Vat/not-allowed-w");
              
                      // urn has no debt, or a non-dusty amount
                      require(either(urn.art == 0, tab >= ilk.dust), "Vat/dust");
              
                      gem[i][v] = sub(gem[i][v], dink);
                      dai[w]    = add(dai[w],    dtab);
              
                      urns[i][u] = urn;
                      ilks[i]    = ilk;
                  }
                  // --- CDP Fungibility ---
                  function fork(bytes32 ilk, address src, address dst, int dink, int dart) external note {
                      Urn storage u = urns[ilk][src];
                      Urn storage v = urns[ilk][dst];
                      Ilk storage i = ilks[ilk];
              
                      u.ink = sub(u.ink, dink);
                      u.art = sub(u.art, dart);
                      v.ink = add(v.ink, dink);
                      v.art = add(v.art, dart);
              
                      uint utab = mul(u.art, i.rate);
                      uint vtab = mul(v.art, i.rate);
              
                      // both sides consent
                      require(both(wish(src, msg.sender), wish(dst, msg.sender)), "Vat/not-allowed");
              
                      // both sides safe
                      require(utab <= mul(u.ink, i.spot), "Vat/not-safe-src");
                      require(vtab <= mul(v.ink, i.spot), "Vat/not-safe-dst");
              
                      // both sides non-dusty
                      require(either(utab >= i.dust, u.art == 0), "Vat/dust-src");
                      require(either(vtab >= i.dust, v.art == 0), "Vat/dust-dst");
                  }
                  // --- CDP Confiscation ---
                  function grab(bytes32 i, address u, address v, address w, int dink, int dart) external note auth {
                      Urn storage urn = urns[i][u];
                      Ilk storage ilk = ilks[i];
              
                      urn.ink = add(urn.ink, dink);
                      urn.art = add(urn.art, dart);
                      ilk.Art = add(ilk.Art, dart);
              
                      int dtab = mul(ilk.rate, dart);
              
                      gem[i][v] = sub(gem[i][v], dink);
                      sin[w]    = sub(sin[w],    dtab);
                      vice      = sub(vice,      dtab);
                  }
              
                  // --- Settlement ---
                  function heal(uint rad) external note {
                      address u = msg.sender;
                      sin[u] = sub(sin[u], rad);
                      dai[u] = sub(dai[u], rad);
                      vice   = sub(vice,   rad);
                      debt   = sub(debt,   rad);
                  }
                  function suck(address u, address v, uint rad) external note auth {
                      sin[u] = add(sin[u], rad);
                      dai[v] = add(dai[v], rad);
                      vice   = add(vice,   rad);
                      debt   = add(debt,   rad);
                  }
              
                  // --- Rates ---
                  function fold(bytes32 i, address u, int rate) external note auth {
                      require(live == 1, "Vat/not-live");
                      Ilk storage ilk = ilks[i];
                      ilk.rate = add(ilk.rate, rate);
                      int rad  = mul(ilk.Art, rate);
                      dai[u]   = add(dai[u], rad);
                      debt     = add(debt,   rad);
                  }
              }

              File 3 of 9: DaiJoin
              // hevm: flattened sources of /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/join.sol
              pragma solidity =0.5.12;
              
              ////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/lib.sol
              // This program is free software: you can redistribute it and/or modify
              // it under the terms of the GNU General Public License as published by
              // the Free Software Foundation, either version 3 of the License, or
              // (at your option) any later version.
              
              // This program is distributed in the hope that it will be useful,
              // but WITHOUT ANY WARRANTY; without even the implied warranty of
              // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
              // GNU General Public License for more details.
              
              // You should have received a copy of the GNU General Public License
              // along with this program.  If not, see <http://www.gnu.org/licenses/>.
              
              /* pragma solidity 0.5.12; */
              
              contract LibNote {
                  event LogNote(
                      bytes4   indexed  sig,
                      address  indexed  usr,
                      bytes32  indexed  arg1,
                      bytes32  indexed  arg2,
                      bytes             data
                  ) anonymous;
              
                  modifier note {
                      _;
                      assembly {
                          // log an 'anonymous' event with a constant 6 words of calldata
                          // and four indexed topics: selector, caller, arg1 and arg2
                          let mark := msize                         // end of memory ensures zero
                          mstore(0x40, add(mark, 288))              // update free memory pointer
                          mstore(mark, 0x20)                        // bytes type data offset
                          mstore(add(mark, 0x20), 224)              // bytes size (padded)
                          calldatacopy(add(mark, 0x40), 0, 224)     // bytes payload
                          log4(mark, 288,                           // calldata
                               shl(224, shr(224, calldataload(0))), // msg.sig
                               caller,                              // msg.sender
                               calldataload(4),                     // arg1
                               calldataload(36)                     // arg2
                              )
                      }
                  }
              }
              
              ////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/join.sol
              /// join.sol -- Basic token adapters
              
              // Copyright (C) 2018 Rain <rainbreak@riseup.net>
              //
              // 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 <https://www.gnu.org/licenses/>.
              
              /* pragma solidity 0.5.12; */
              
              /* import "./lib.sol"; */
              
              contract GemLike {
                  function decimals() public view returns (uint);
                  function transfer(address,uint) external returns (bool);
                  function transferFrom(address,address,uint) external returns (bool);
              }
              
              contract DSTokenLike {
                  function mint(address,uint) external;
                  function burn(address,uint) external;
              }
              
              contract VatLike {
                  function slip(bytes32,address,int) external;
                  function move(address,address,uint) external;
              }
              
              /*
                  Here we provide *adapters* to connect the Vat to arbitrary external
                  token implementations, creating a bounded context for the Vat. The
                  adapters here are provided as working examples:
              
                    - `GemJoin`: For well behaved ERC20 tokens, with simple transfer
                                 semantics.
              
                    - `ETHJoin`: For native Ether.
              
                    - `DaiJoin`: For connecting internal Dai balances to an external
                                 `DSToken` implementation.
              
                  In practice, adapter implementations will be varied and specific to
                  individual collateral types, accounting for different transfer
                  semantics and token standards.
              
                  Adapters need to implement two basic methods:
              
                    - `join`: enter collateral into the system
                    - `exit`: remove collateral from the system
              
              */
              
              contract GemJoin is LibNote {
                  // --- Auth ---
                  mapping (address => uint) public wards;
                  function rely(address usr) external note auth { wards[usr] = 1; }
                  function deny(address usr) external note auth { wards[usr] = 0; }
                  modifier auth {
                      require(wards[msg.sender] == 1, "GemJoin/not-authorized");
                      _;
                  }
              
                  VatLike public vat;
                  bytes32 public ilk;
                  GemLike public gem;
                  uint    public dec;
                  uint    public live;  // Access Flag
              
                  constructor(address vat_, bytes32 ilk_, address gem_) public {
                      wards[msg.sender] = 1;
                      live = 1;
                      vat = VatLike(vat_);
                      ilk = ilk_;
                      gem = GemLike(gem_);
                      dec = gem.decimals();
                  }
                  function cage() external note auth {
                      live = 0;
                  }
                  function join(address usr, uint wad) external note {
                      require(live == 1, "GemJoin/not-live");
                      require(int(wad) >= 0, "GemJoin/overflow");
                      vat.slip(ilk, usr, int(wad));
                      require(gem.transferFrom(msg.sender, address(this), wad), "GemJoin/failed-transfer");
                  }
                  function exit(address usr, uint wad) external note {
                      require(wad <= 2 ** 255, "GemJoin/overflow");
                      vat.slip(ilk, msg.sender, -int(wad));
                      require(gem.transfer(usr, wad), "GemJoin/failed-transfer");
                  }
              }
              
              contract ETHJoin is LibNote {
                  // --- Auth ---
                  mapping (address => uint) public wards;
                  function rely(address usr) external note auth { wards[usr] = 1; }
                  function deny(address usr) external note auth { wards[usr] = 0; }
                  modifier auth {
                      require(wards[msg.sender] == 1, "ETHJoin/not-authorized");
                      _;
                  }
              
                  VatLike public vat;
                  bytes32 public ilk;
                  uint    public live;  // Access Flag
              
                  constructor(address vat_, bytes32 ilk_) public {
                      wards[msg.sender] = 1;
                      live = 1;
                      vat = VatLike(vat_);
                      ilk = ilk_;
                  }
                  function cage() external note auth {
                      live = 0;
                  }
                  function join(address usr) external payable note {
                      require(live == 1, "ETHJoin/not-live");
                      require(int(msg.value) >= 0, "ETHJoin/overflow");
                      vat.slip(ilk, usr, int(msg.value));
                  }
                  function exit(address payable usr, uint wad) external note {
                      require(int(wad) >= 0, "ETHJoin/overflow");
                      vat.slip(ilk, msg.sender, -int(wad));
                      usr.transfer(wad);
                  }
              }
              
              contract DaiJoin is LibNote {
                  // --- Auth ---
                  mapping (address => uint) public wards;
                  function rely(address usr) external note auth { wards[usr] = 1; }
                  function deny(address usr) external note auth { wards[usr] = 0; }
                  modifier auth {
                      require(wards[msg.sender] == 1, "DaiJoin/not-authorized");
                      _;
                  }
              
                  VatLike public vat;
                  DSTokenLike public dai;
                  uint    public live;  // Access Flag
              
                  constructor(address vat_, address dai_) public {
                      wards[msg.sender] = 1;
                      live = 1;
                      vat = VatLike(vat_);
                      dai = DSTokenLike(dai_);
                  }
                  function cage() external note auth {
                      live = 0;
                  }
                  uint constant ONE = 10 ** 27;
                  function mul(uint x, uint y) internal pure returns (uint z) {
                      require(y == 0 || (z = x * y) / y == x);
                  }
                  function join(address usr, uint wad) external note {
                      vat.move(address(this), usr, mul(ONE, wad));
                      dai.burn(msg.sender, wad);
                  }
                  function exit(address usr, uint wad) external note {
                      require(live == 1, "DaiJoin/not-live");
                      vat.move(msg.sender, address(this), mul(ONE, wad));
                      dai.mint(usr, wad);
                  }
              }

              File 4 of 9: DssCdpManager
              // hevm: flattened sources of /nix/store/jyvwn5yyqxwkfxc45k04h2dk209dn6sh-dss-cdp-manager-8976239/src/DssCdpManager.sol
              pragma solidity =0.5.12;
              
              ////// /nix/store/4vip6nyqfd0yhs15md21rzxsk5jgx6sv-dss/dapp/dss/src/lib.sol
              // This program is free software: you can redistribute it and/or modify
              // it under the terms of the GNU General Public License as published by
              // the Free Software Foundation, either version 3 of the License, or
              // (at your option) any later version.
              
              // This program is distributed in the hope that it will be useful,
              // but WITHOUT ANY WARRANTY; without even the implied warranty of
              // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
              // GNU General Public License for more details.
              
              // You should have received a copy of the GNU General Public License
              // along with this program.  If not, see <http://www.gnu.org/licenses/>.
              
              /* pragma solidity 0.5.12; */
              
              contract LibNote {
                  event LogNote(
                      bytes4   indexed  sig,
                      address  indexed  usr,
                      bytes32  indexed  arg1,
                      bytes32  indexed  arg2,
                      bytes             data
                  ) anonymous;
              
                  modifier note {
                      _;
                      assembly {
                          // log an 'anonymous' event with a constant 6 words of calldata
                          // and four indexed topics: selector, caller, arg1 and arg2
                          let mark := msize                         // end of memory ensures zero
                          mstore(0x40, add(mark, 288))              // update free memory pointer
                          mstore(mark, 0x20)                        // bytes type data offset
                          mstore(add(mark, 0x20), 224)              // bytes size (padded)
                          calldatacopy(add(mark, 0x40), 0, 224)     // bytes payload
                          log4(mark, 288,                           // calldata
                               shl(224, shr(224, calldataload(0))), // msg.sig
                               caller,                              // msg.sender
                               calldataload(4),                     // arg1
                               calldataload(36)                     // arg2
                              )
                      }
                  }
              }
              
              ////// /nix/store/jyvwn5yyqxwkfxc45k04h2dk209dn6sh-dss-cdp-manager-8976239/src/DssCdpManager.sol
              /* pragma solidity 0.5.12; */
              
              /* import { LibNote } from "dss/lib.sol"; */
              
              contract VatLike {
                  function urns(bytes32, address) public view returns (uint, uint);
                  function hope(address) public;
                  function flux(bytes32, address, address, uint) public;
                  function move(address, address, uint) public;
                  function frob(bytes32, address, address, address, int, int) public;
                  function fork(bytes32, address, address, int, int) public;
              }
              
              contract UrnHandler {
                  constructor(address vat) public {
                      VatLike(vat).hope(msg.sender);
                  }
              }
              
              contract DssCdpManager is LibNote {
                  address                   public vat;
                  uint                      public cdpi;      // Auto incremental
                  mapping (uint => address) public urns;      // CDPId => UrnHandler
                  mapping (uint => List)    public list;      // CDPId => Prev & Next CDPIds (double linked list)
                  mapping (uint => address) public owns;      // CDPId => Owner
                  mapping (uint => bytes32) public ilks;      // CDPId => Ilk
              
                  mapping (address => uint) public first;     // Owner => First CDPId
                  mapping (address => uint) public last;      // Owner => Last CDPId
                  mapping (address => uint) public count;     // Owner => Amount of CDPs
              
                  mapping (
                      address => mapping (
                          uint => mapping (
                              address => uint
                          )
                      )
                  ) public cdpCan;                            // Owner => CDPId => Allowed Addr => True/False
              
                  mapping (
                      address => mapping (
                          address => uint
                      )
                  ) public urnCan;                            // Urn => Allowed Addr => True/False
              
                  struct List {
                      uint prev;
                      uint next;
                  }
              
                  event NewCdp(address indexed usr, address indexed own, uint indexed cdp);
              
                  modifier cdpAllowed(
                      uint cdp
                  ) {
                      require(msg.sender == owns[cdp] || cdpCan[owns[cdp]][cdp][msg.sender] == 1, "cdp-not-allowed");
                      _;
                  }
              
                  modifier urnAllowed(
                      address urn
                  ) {
                      require(msg.sender == urn || urnCan[urn][msg.sender] == 1, "urn-not-allowed");
                      _;
                  }
              
                  constructor(address vat_) public {
                      vat = vat_;
                  }
              
                  function add(uint x, uint y) internal pure returns (uint z) {
                      require((z = x + y) >= x);
                  }
              
                  function sub(uint x, uint y) internal pure returns (uint z) {
                      require((z = x - y) <= x);
                  }
              
                  function toInt(uint x) internal pure returns (int y) {
                      y = int(x);
                      require(y >= 0);
                  }
              
                  // Allow/disallow a usr address to manage the cdp.
                  function cdpAllow(
                      uint cdp,
                      address usr,
                      uint ok
                  ) public cdpAllowed(cdp) {
                      cdpCan[owns[cdp]][cdp][usr] = ok;
                  }
              
                  // Allow/disallow a usr address to quit to the the sender urn.
                  function urnAllow(
                      address usr,
                      uint ok
                  ) public {
                      urnCan[msg.sender][usr] = ok;
                  }
              
                  // Open a new cdp for a given usr address.
                  function open(
                      bytes32 ilk,
                      address usr
                  ) public note returns (uint) {
                      require(usr != address(0), "usr-address-0");
              
                      cdpi = add(cdpi, 1);
                      urns[cdpi] = address(new UrnHandler(vat));
                      owns[cdpi] = usr;
                      ilks[cdpi] = ilk;
              
                      // Add new CDP to double linked list and pointers
                      if (first[usr] == 0) {
                          first[usr] = cdpi;
                      }
                      if (last[usr] != 0) {
                          list[cdpi].prev = last[usr];
                          list[last[usr]].next = cdpi;
                      }
                      last[usr] = cdpi;
                      count[usr] = add(count[usr], 1);
              
                      emit NewCdp(msg.sender, usr, cdpi);
                      return cdpi;
                  }
              
                  // Give the cdp ownership to a dst address.
                  function give(
                      uint cdp,
                      address dst
                  ) public note cdpAllowed(cdp) {
                      require(dst != address(0), "dst-address-0");
                      require(dst != owns[cdp], "dst-already-owner");
              
                      // Remove transferred CDP from double linked list of origin user and pointers
                      if (list[cdp].prev != 0) {
                          list[list[cdp].prev].next = list[cdp].next;         // Set the next pointer of the prev cdp (if exists) to the next of the transferred one
                      }
                      if (list[cdp].next != 0) {                              // If wasn't the last one
                          list[list[cdp].next].prev = list[cdp].prev;         // Set the prev pointer of the next cdp to the prev of the transferred one
                      } else {                                                // If was the last one
                          last[owns[cdp]] = list[cdp].prev;                   // Update last pointer of the owner
                      }
                      if (first[owns[cdp]] == cdp) {                          // If was the first one
                          first[owns[cdp]] = list[cdp].next;                  // Update first pointer of the owner
                      }
                      count[owns[cdp]] = sub(count[owns[cdp]], 1);
              
                      // Transfer ownership
                      owns[cdp] = dst;
              
                      // Add transferred CDP to double linked list of destiny user and pointers
                      list[cdp].prev = last[dst];
                      list[cdp].next = 0;
                      if (last[dst] != 0) {
                          list[last[dst]].next = cdp;
                      }
                      if (first[dst] == 0) {
                          first[dst] = cdp;
                      }
                      last[dst] = cdp;
                      count[dst] = add(count[dst], 1);
                  }
              
                  // Frob the cdp keeping the generated DAI or collateral freed in the cdp urn address.
                  function frob(
                      uint cdp,
                      int dink,
                      int dart
                  ) public note cdpAllowed(cdp) {
                      address urn = urns[cdp];
                      VatLike(vat).frob(
                          ilks[cdp],
                          urn,
                          urn,
                          urn,
                          dink,
                          dart
                      );
                  }
              
                  // Transfer wad amount of cdp collateral from the cdp address to a dst address.
                  function flux(
                      uint cdp,
                      address dst,
                      uint wad
                  ) public note cdpAllowed(cdp) {
                      VatLike(vat).flux(ilks[cdp], urns[cdp], dst, wad);
                  }
              
                  // Transfer wad amount of any type of collateral (ilk) from the cdp address to a dst address.
                  // This function has the purpose to take away collateral from the system that doesn't correspond to the cdp but was sent there wrongly.
                  function flux(
                      bytes32 ilk,
                      uint cdp,
                      address dst,
                      uint wad
                  ) public note cdpAllowed(cdp) {
                      VatLike(vat).flux(ilk, urns[cdp], dst, wad);
                  }
              
                  // Transfer wad amount of DAI from the cdp address to a dst address.
                  function move(
                      uint cdp,
                      address dst,
                      uint rad
                  ) public note cdpAllowed(cdp) {
                      VatLike(vat).move(urns[cdp], dst, rad);
                  }
              
                  // Quit the system, migrating the cdp (ink, art) to a different dst urn
                  function quit(
                      uint cdp,
                      address dst
                  ) public note cdpAllowed(cdp) urnAllowed(dst) {
                      (uint ink, uint art) = VatLike(vat).urns(ilks[cdp], urns[cdp]);
                      VatLike(vat).fork(
                          ilks[cdp],
                          urns[cdp],
                          dst,
                          toInt(ink),
                          toInt(art)
                      );
                  }
              
                  // Import a position from src urn to the urn owned by cdp
                  function enter(
                      address src,
                      uint cdp
                  ) public note urnAllowed(src) cdpAllowed(cdp) {
                      (uint ink, uint art) = VatLike(vat).urns(ilks[cdp], src);
                      VatLike(vat).fork(
                          ilks[cdp],
                          src,
                          urns[cdp],
                          toInt(ink),
                          toInt(art)
                      );
                  }
              
                  // Move a position from cdpSrc urn to the cdpDst urn
                  function shift(
                      uint cdpSrc,
                      uint cdpDst
                  ) public note cdpAllowed(cdpSrc) cdpAllowed(cdpDst) {
                      require(ilks[cdpSrc] == ilks[cdpDst], "non-matching-cdps");
                      (uint ink, uint art) = VatLike(vat).urns(ilks[cdpSrc], urns[cdpSrc]);
                      VatLike(vat).fork(
                          ilks[cdpSrc],
                          urns[cdpSrc],
                          urns[cdpDst],
                          toInt(ink),
                          toInt(art)
                      );
                  }
              }

              File 5 of 9: InstaAccountV2
              // SPDX-License-Identifier: MIT
              pragma solidity ^0.7.0;
              interface AccountImplementations {
                  function getImplementation(bytes4 _sig) external view returns (address);
              }
              /**
               * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
               * instruction `delegatecall`.
               */
              contract InstaAccountV2 {
                  AccountImplementations public immutable implementations;
                  constructor(address _implementations) {
                      implementations = AccountImplementations(_implementations);
                  }
                  /**
                   * @dev Delegates the current call to `implementation`.
                   * 
                   * This function does not return to its internall call site, it will return directly to the external caller.
                   */
                  function _delegate(address implementation) internal {
                      // solhint-disable-next-line no-inline-assembly
                      assembly {
                          // Copy msg.data. We take full control of memory in this inline assembly
                          // block because it will not return to Solidity code. We overwrite the
                          // Solidity scratch pad at memory position 0.
                          calldatacopy(0, 0, calldatasize())
                          // Call the implementation.
                          // out and outsize are 0 because we don't know the size yet.
                          let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
                          // Copy the returned data.
                          returndatacopy(0, 0, returndatasize())
                          switch result
                          // delegatecall returns 0 on error.
                          case 0 { revert(0, returndatasize()) }
                          default { return(0, returndatasize()) }
                      }
                  }
                  /**
                   * @dev Delegates the current call to the address returned by Implementations registry.
                   * 
                   * This function does not return to its internall call site, it will return directly to the external caller.
                   */
                  function _fallback(bytes4 _sig) internal {
                      address _implementation = implementations.getImplementation(_sig);
                      require(_implementation != address(0), "InstaAccountV2: Not able to find _implementation");
                      _delegate(_implementation);
                  }
                  /**
                   * @dev Fallback function that delegates calls to the address returned by Implementations registry.
                   */
                  fallback () external payable {
                      _fallback(msg.sig);
                  }
                  /**
                   * @dev Fallback function that delegates calls to the address returned by Implementations registry.
                   */
                  receive () external payable {
                      if (msg.sig != 0x00000000) {
                          _fallback(msg.sig);
                      }
                  }
              }
              

              File 6 of 9: InstaImplementations
              // SPDX-License-Identifier: MIT
              pragma solidity ^0.7.0;
              interface IndexInterface {
                  function master() external view returns (address);
              }
              contract Setup {
                  address public defaultImplementation;
                  mapping (bytes4 => address) internal sigImplementations;
                  mapping (address => bytes4[]) internal implementationSigs;
              }
              contract Implementations is Setup {
                  event LogSetDefaultImplementation(address indexed oldImplementation, address indexed newImplementation);
                  event LogAddImplementation(address indexed implementation, bytes4[] sigs);
                  event LogRemoveImplementation(address indexed implementation, bytes4[] sigs);
                  IndexInterface constant public instaIndex = IndexInterface(0x2971AdFa57b20E5a416aE5a708A8655A9c74f723);
                  modifier isMaster() {
                      require(msg.sender == instaIndex.master(), "Implementations: not-master");
                      _;
                  }
                  function setDefaultImplementation(address _defaultImplementation) external isMaster {
                      require(_defaultImplementation != address(0), "Implementations: _defaultImplementation address not valid");
                      require(_defaultImplementation != defaultImplementation, "Implementations: _defaultImplementation cannot be same");
                      emit LogSetDefaultImplementation(defaultImplementation, _defaultImplementation);
                      defaultImplementation = _defaultImplementation;
                  }
                  function addImplementation(address _implementation, bytes4[] calldata _sigs) external isMaster {
                      require(_implementation != address(0), "Implementations: _implementation not valid.");
                      require(implementationSigs[_implementation].length == 0, "Implementations: _implementation already added.");
                      for (uint i = 0; i < _sigs.length; i++) {
                          bytes4 _sig = _sigs[i];
                          require(sigImplementations[_sig] == address(0), "Implementations: _sig already added");
                          sigImplementations[_sig] = _implementation;
                      }
                      implementationSigs[_implementation] = _sigs;
                      emit LogAddImplementation(_implementation, _sigs);
                  }
                  function removeImplementation(address _implementation) external isMaster {
                      require(_implementation != address(0), "Implementations: _implementation not valid.");
                      require(implementationSigs[_implementation].length != 0, "Implementations: _implementation not found.");
                      bytes4[] memory sigs = implementationSigs[_implementation];
                      for (uint i = 0; i < sigs.length; i++) {
                          bytes4 sig = sigs[i];
                          delete sigImplementations[sig];
                      }
                      delete implementationSigs[_implementation];
                      emit LogRemoveImplementation(_implementation, sigs);
                  }
              }
              contract InstaImplementations is Implementations {
                  function getImplementation(bytes4 _sig) external view returns (address) {
                      address _implementation = sigImplementations[_sig];
                      return _implementation == address(0) ? defaultImplementation : _implementation;
                  }
                  function getImplementationSigs(address _impl) external view returns (bytes4[] memory) {
                      return implementationSigs[_impl];
                  }
                  function getSigImplementation(bytes4 _sig) external view returns (address) {
                      return sigImplementations[_sig];
                  }
              }
              

              File 7 of 9: InstaImplementationM1
              pragma solidity ^0.7.0;
              pragma experimental ABIEncoderV2;
              import { Variables } from "./variables.sol";
              /**
               * @title InstaAccountV2.
               * @dev DeFi Smart Account Wallet.
               */
              interface ConnectorsInterface {
                  function isConnectors(string[] calldata connectorNames) external view returns (bool, address[] memory);
              }
              contract Constants is Variables {
                  // InstaIndex Address.
                  address internal immutable instaIndex;
                  // Connectors Address.
                  address public immutable connectorsM1;
                  constructor(address _instaIndex, address _connectors) {
                      connectorsM1 = _connectors;
                      instaIndex = _instaIndex;
                  }
              }
              contract InstaImplementationM1 is Constants {
                  constructor(address _instaIndex, address _connectors) Constants(_instaIndex, _connectors) {}
                  function decodeEvent(bytes memory response) internal pure returns (string memory _eventCode, bytes memory _eventParams) {
                      if (response.length > 0) {
                          (_eventCode, _eventParams) = abi.decode(response, (string, bytes));
                      }
                  }
                  event LogCast(
                      address indexed origin,
                      address indexed sender,
                      uint256 value,
                      string[] targetsNames,
                      address[] targets,
                      string[] eventNames,
                      bytes[] eventParams
                  );
                  receive() external payable {}
                   /**
                   * @dev Delegate the calls to Connector.
                   * @param _target Connector address
                   * @param _data CallData of function.
                  */
                  function spell(address _target, bytes memory _data) internal returns (bytes memory response) {
                      require(_target != address(0), "target-invalid");
                      assembly {
                          let succeeded := delegatecall(gas(), _target, add(_data, 0x20), mload(_data), 0, 0)
                          let size := returndatasize()
                          
                          response := mload(0x40)
                          mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
                          mstore(response, size)
                          returndatacopy(add(response, 0x20), 0, size)
                          switch iszero(succeeded)
                              case 1 {
                                  // throw if delegatecall failed
                                  returndatacopy(0x00, 0x00, size)
                                  revert(0x00, size)
                              }
                      }
                  }
                  /**
                   * @dev This is the main function, Where all the different functions are called
                   * from Smart Account.
                   * @param _targetNames Array of Connector address.
                   * @param _datas Array of Calldata.
                  */
                  function cast(
                      string[] calldata _targetNames,
                      bytes[] calldata _datas,
                      address _origin
                  )
                  external
                  payable 
                  returns (bytes32) // Dummy return to fix instaIndex buildWithCast function
                  {   
                      uint256 _length = _targetNames.length;
                      require(_auth[msg.sender] || msg.sender == instaIndex, "1: permission-denied");
                      require(_length != 0, "1: length-invalid");
                      require(_length == _datas.length , "1: array-length-invalid");
                      string[] memory eventNames = new string[](_length);
                      bytes[] memory eventParams = new bytes[](_length);
                      (bool isOk, address[] memory _targets) = ConnectorsInterface(connectorsM1).isConnectors(_targetNames);
                      require(isOk, "1: not-connector");
                      for (uint i = 0; i < _length; i++) {
                          bytes memory response = spell(_targets[i], _datas[i]);
                          (eventNames[i], eventParams[i]) = decodeEvent(response);
                      }
                      emit LogCast(
                          _origin,
                          msg.sender,
                          msg.value,
                          _targetNames,
                          _targets,
                          eventNames,
                          eventParams
                      );
                  }
              }pragma solidity ^0.7.0;
              contract Variables {
                  // Auth Module(Address of Auth => bool).
                  mapping (address => bool) internal _auth;
              }

              File 8 of 9: InstaConnectorsV2
              pragma solidity ^0.7.0;
              pragma experimental ABIEncoderV2;
              /**
               * @title InstaConnectorsV2
               * @dev Registry for Connectors.
               */
              interface IndexInterface {
                  function master() external view returns (address);
              }
              interface ConnectorInterface {
                  function name() external view returns (string memory);
              }
              contract Controllers {
                  event LogController(address indexed addr, bool indexed isChief);
                  // InstaIndex Address.
                  address public immutable instaIndex;
                  constructor(address _instaIndex) {
                      instaIndex = _instaIndex;
                  }
                  // Enabled Chief(Address of Chief => bool).
                  mapping(address => bool) public chief;
                  // Enabled Connectors(Connector name => address).
                  mapping(string => address) public connectors;
                  /**
                  * @dev Throws if the sender not is Master Address from InstaIndex
                  * or Enabled Chief.
                  */
                  modifier isChief {
                      require(chief[msg.sender] || msg.sender == IndexInterface(instaIndex).master(), "not-an-chief");
                      _;
                  }
                  /**
                   * @dev Toggle a Chief. Enable if disable & vice versa
                   * @param _chiefAddress Chief Address.
                  */
                  function toggleChief(address _chiefAddress) external {
                      require(msg.sender == IndexInterface(instaIndex).master(), "toggleChief: not-master");
                      chief[_chiefAddress] = !chief[_chiefAddress];
                      emit LogController(_chiefAddress, chief[_chiefAddress]);
                  }
              }
              contract InstaConnectorsV2 is Controllers {
                  event LogConnectorAdded(
                      bytes32 indexed connectorNameHash,
                      string connectorName,
                      address indexed connector
                  );
                  event LogConnectorUpdated(
                      bytes32 indexed connectorNameHash,
                      string connectorName,
                      address indexed oldConnector,
                      address indexed newConnector
                  );
                  event LogConnectorRemoved(
                      bytes32 indexed connectorNameHash,
                      string connectorName,
                      address indexed connector
                  );
                  constructor(address _instaIndex) public Controllers(_instaIndex) {}
                  /**
                   * @dev Add Connectors
                   * @param _connectorNames Array of Connector Names.
                   * @param _connectors Array of Connector Address.
                  */
                  function addConnectors(string[] calldata _connectorNames, address[] calldata _connectors) external isChief {
                      require(_connectors.length == _connectors.length, "addConnectors: not same length");
                      for (uint i = 0; i < _connectors.length; i++) {
                          require(connectors[_connectorNames[i]] == address(0), "addConnectors: _connectorName added already");
                          require(_connectors[i] != address(0), "addConnectors: _connectors address not vaild");
                          ConnectorInterface(_connectors[i]).name(); // Checking if connector has function name()
                          connectors[_connectorNames[i]] = _connectors[i];
                          emit LogConnectorAdded(keccak256(abi.encodePacked(_connectorNames[i])), _connectorNames[i], _connectors[i]);
                      }
                  }
                  /**
                   * @dev Update Connectors
                   * @param _connectorNames Array of Connector Names.
                   * @param _connectors Array of Connector Address.
                  */
                  function updateConnectors(string[] calldata _connectorNames, address[] calldata _connectors) external isChief {
                      require(_connectorNames.length == _connectors.length, "updateConnectors: not same length");
                      for (uint i = 0; i < _connectors.length; i++) {
                          require(connectors[_connectorNames[i]] != address(0), "updateConnectors: _connectorName not added to update");
                          require(_connectors[i] != address(0), "updateConnectors: _connector address is not vaild");
                          ConnectorInterface(_connectors[i]).name(); // Checking if connector has function name()
                          emit LogConnectorUpdated(keccak256(abi.encodePacked(_connectorNames[i])), _connectorNames[i], connectors[_connectorNames[i]], _connectors[i]);
                          connectors[_connectorNames[i]] = _connectors[i];
                      }
                  }
                  /**
                   * @dev Remove Connectors
                   * @param _connectorNames Array of Connector Names.
                  */
                  function removeConnectors(string[] calldata _connectorNames) external isChief {
                      for (uint i = 0; i < _connectorNames.length; i++) {
                          require(connectors[_connectorNames[i]] != address(0), "removeConnectors: _connectorName not added to update");
                          emit LogConnectorRemoved(keccak256(abi.encodePacked(_connectorNames[i])), _connectorNames[i], connectors[_connectorNames[i]]);
                          delete connectors[_connectorNames[i]];
                      }
                  }
                  /**
                   * @dev Check if Connector addresses are enabled.
                   * @param _connectors Array of Connector Names.
                  */
                  function isConnectors(string[] calldata _connectorNames) external view returns (bool isOk, address[] memory _connectors) {
                      isOk = true;
                      uint len = _connectorNames.length;
                      _connectors = new address[](len);
                      for (uint i = 0; i < _connectors.length; i++) {
                          _connectors[i] = connectors[_connectorNames[i]];
                          if (_connectors[i] == address(0)) {
                              isOk = false;
                              break;
                          }
                      }
                  }
              }

              File 9 of 9: ConnectV2MakerDAO
              pragma solidity ^0.7.0;
              /**
               * @title MakerDAO.
               * @dev Collateralized Borrowing.
               */
              import { TokenInterface, AccountInterface } from "../../common/interfaces.sol";
              import { Helpers } from "./helpers.sol";
              import { Events } from "./events.sol";
              import { VatLike, TokenJoinInterface } from "./interface.sol";
              abstract contract MakerResolver is Helpers, Events {
                  /**
                   * @dev Open Vault
                   * @notice Open a MakerDAO Vault
                   * @param colType Type of Collateral.(eg: 'ETH-A')
                  */
                  function open(string calldata colType) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      bytes32 ilk = stringToBytes32(colType);
                      require(instaMapping.gemJoinMapping(ilk) != address(0), "wrong-col-type");
                      uint256 vault = managerContract.open(ilk, address(this));
                      _eventName = "LogOpen(uint256,bytes32)";
                      _eventParam = abi.encode(vault, ilk);
                  }
                  /**
                   * @dev Close Vault
                   * @notice Close a MakerDAO Vault
                   * @param vault Vault ID to close.
                  */
                  function close(uint256 vault) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      uint _vault = getVault(vault);
                      (bytes32 ilk, address urn) = getVaultData(_vault);
                      (uint ink, uint art) = VatLike(managerContract.vat()).urns(ilk, urn);
                      require(ink == 0 && art == 0, "vault-has-assets");
                      require(managerContract.owns(_vault) == address(this), "not-owner");
                      managerContract.give(_vault, giveAddr);
                      _eventName = "LogClose(uint256,bytes32)";
                      _eventParam = abi.encode(_vault, ilk);
                  }
                  /**
                   * @dev Transfer Vault
                   * @notice Transfer a MakerDAO Vault to "nextOwner"
                   * @param vault Vault ID to close.
                   * @param nextOwner Address of the next owner of the vault.
                  */
                  function transfer(
                      uint vault,
                      address nextOwner
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      require(AccountInterface(address(this)).isAuth(nextOwner), "nextOwner-is-not-auth");
                      uint256 _vault = getVault(vault);
                      (bytes32 ilk,) = getVaultData(_vault);
                      require(managerContract.owns(_vault) == address(this), "not-owner");
                      managerContract.give(_vault, nextOwner);
                      _eventName = "LogTransfer(uint256,bytes32,address)";
                      _eventParam = abi.encode(_vault, ilk, nextOwner);
                  }
                  /**
                   * @dev Deposit ETH/ERC20_Token Collateral.
                   * @notice Deposit collateral to a MakerDAO vault
                   * @param vault Vault ID. (Use 0 for last opened vault)
                   * @param amt The amount of tokens to deposit. (For max: `uint256(-1)`)
                   * @param getId ID to retrieve amt.
                   * @param setId ID stores the amount of tokens deposited.
                  */
                  function deposit(
                      uint256 vault,
                      uint256 amt,
                      uint256 getId,
                      uint256 setId
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      uint _amt = getUint(getId, amt);
                      uint _vault = getVault(vault);
                      (bytes32 ilk, address urn) = getVaultData(_vault);
                      address colAddr = instaMapping.gemJoinMapping(ilk);
                      TokenJoinInterface tokenJoinContract = TokenJoinInterface(colAddr);
                      TokenInterface tokenContract = tokenJoinContract.gem();
                      if (isEth(address(tokenContract))) {
                          _amt = _amt == uint(-1) ? address(this).balance : _amt;
                          tokenContract.deposit{value: _amt}();
                      } else {
                          _amt = _amt == uint(-1) ?  tokenContract.balanceOf(address(this)) : _amt;
                      }
                      approve(tokenContract, address(colAddr), _amt);
                      tokenJoinContract.join(address(this), _amt);
                      VatLike(managerContract.vat()).frob(
                          ilk,
                          urn,
                          address(this),
                          address(this),
                          toInt(convertTo18(tokenJoinContract.dec(), _amt)),
                          0
                      );
                      setUint(setId, _amt);
                      _eventName = "LogDeposit(uint256,bytes32,uint256,uint256,uint256)";
                      _eventParam = abi.encode(_vault, ilk, _amt, getId, setId);
                  }
                  /**
                   * @dev Withdraw ETH/ERC20_Token Collateral.
                   * @notice Withdraw collateral from a MakerDAO vault
                   * @param vault Vault ID. (Use 0 for last opened vault)
                   * @param amt The amount of tokens to withdraw. (For max: `uint256(-1)`)
                   * @param getId ID to retrieve amt.
                   * @param setId ID stores the amount of tokens withdrawn.
                  */
                  function withdraw(
                      uint256 vault,
                      uint256 amt,
                      uint256 getId,
                      uint256 setId
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      uint _amt = getUint(getId, amt);
                      uint _vault = getVault(vault);
                      (bytes32 ilk, address urn) = getVaultData(_vault);
                      address colAddr = instaMapping.gemJoinMapping(ilk);
                      TokenJoinInterface tokenJoinContract = TokenJoinInterface(colAddr);
                      uint _amt18;
                      if (_amt == uint(-1)) {
                          (_amt18,) = VatLike(managerContract.vat()).urns(ilk, urn);
                          _amt = convert18ToDec(tokenJoinContract.dec(), _amt18);
                      } else {
                          _amt18 = convertTo18(tokenJoinContract.dec(), _amt);
                      }
                      managerContract.frob(
                          _vault,
                          -toInt(_amt18),
                          0
                      );
                      managerContract.flux(
                          _vault,
                          address(this),
                          _amt18
                      );
                      TokenInterface tokenContract = tokenJoinContract.gem();
                      if (isEth(address(tokenContract))) {
                          tokenJoinContract.exit(address(this), _amt);
                          tokenContract.withdraw(_amt);
                      } else {
                          tokenJoinContract.exit(address(this), _amt);
                      }
                      setUint(setId, _amt);
                      _eventName = "LogWithdraw(uint256,bytes32,uint256,uint256,uint256)";
                      _eventParam = abi.encode(_vault, ilk, _amt, getId, setId);
                  }
                  /**
                   * @dev Borrow DAI.
                   * @notice Borrow DAI using a MakerDAO vault
                   * @param vault Vault ID. (Use 0 for last opened vault)
                   * @param amt The amount of DAI to borrow.
                   * @param getId ID to retrieve amt.
                   * @param setId ID stores the amount of DAI borrowed.
                  */
                  function borrow(
                      uint256 vault,
                      uint256 amt,
                      uint256 getId,
                      uint256 setId
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      uint _amt = getUint(getId, amt);
                      uint _vault = getVault(vault);
                      (bytes32 ilk, address urn) = getVaultData(_vault);
                      VatLike vatContract = VatLike(managerContract.vat());
                      managerContract.frob(
                          _vault,
                          0,
                          _getBorrowAmt(
                              address(vatContract),
                              urn,
                              ilk,
                              _amt
                          )
                      );
                      managerContract.move(
                          _vault,
                          address(this),
                          toRad(_amt)
                      );
                      if (vatContract.can(address(this), address(daiJoinContract)) == 0) {
                          vatContract.hope(address(daiJoinContract));
                      }
                      daiJoinContract.exit(address(this), _amt);
                      setUint(setId, _amt);
                      _eventName = "LogBorrow(uint256,bytes32,uint256,uint256,uint256)";
                      _eventParam = abi.encode(_vault, ilk, _amt, getId, setId);
                  }
                  /**
                   * @dev Payback borrowed DAI.
                   * @notice Payback DAI debt owed by a MakerDAO vault
                   * @param vault Vault ID. (Use 0 for last opened vault)
                   * @param amt The amount of DAI to payback. (For max: `uint256(-1)`)
                   * @param getId ID to retrieve amt.
                   * @param setId ID stores the amount of DAI paid back.
                  */
                  function payback(
                      uint256 vault,
                      uint256 amt,
                      uint256 getId,
                      uint256 setId
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      uint _amt = getUint(getId, amt);
                      uint _vault = getVault(vault);
                      (bytes32 ilk, address urn) = getVaultData(_vault);
                      address vat = managerContract.vat();
                      uint _maxDebt = _getVaultDebt(vat, ilk, urn);
                      _amt = _amt == uint(-1) ? _maxDebt : _amt;
                      require(_maxDebt >= _amt, "paying-excess-debt");
                      approve(daiJoinContract.dai(), address(daiJoinContract), _amt);
                      daiJoinContract.join(urn, _amt);
                      managerContract.frob(
                          _vault,
                          0,
                          _getWipeAmt(
                              vat,
                              VatLike(vat).dai(urn),
                              urn,
                              ilk
                          )
                      );
                      setUint(setId, _amt);
                      _eventName = "LogPayback(uint256,bytes32,uint256,uint256,uint256)";
                      _eventParam = abi.encode(_vault, ilk, _amt, getId, setId);
                  }
                  /**
                   * @dev Withdraw leftover ETH/ERC20_Token after Liquidation.
                   * @notice Withdraw leftover collateral after Liquidation.
                   * @param vault Vault ID. (Use 0 for last opened vault)
                   * @param amt token amount to Withdraw. (For max: `uint256(-1)`)
                   * @param getId ID to retrieve amt.
                   * @param setId ID stores the amount of collateral withdrawn.
                  */
                  function withdrawLiquidated(
                      uint256 vault,
                      uint256 amt,
                      uint256 getId,
                      uint256 setId
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      uint _amt = getUint(getId, amt);
                      (bytes32 ilk, address urn) = getVaultData(vault);
                      address colAddr = instaMapping.gemJoinMapping(ilk);
                      TokenJoinInterface tokenJoinContract = TokenJoinInterface(colAddr);
                      uint _amt18;
                      if (_amt == uint(-1)) {
                          _amt18 = VatLike(managerContract.vat()).gem(ilk, urn);
                          _amt = convert18ToDec(tokenJoinContract.dec(), _amt18);
                      } else {
                          _amt18 = convertTo18(tokenJoinContract.dec(), _amt);
                      }
                      managerContract.flux(
                          vault,
                          address(this),
                          _amt18
                      );
                      TokenInterface tokenContract = tokenJoinContract.gem();
                      tokenJoinContract.exit(address(this), _amt);
                      if (isEth(address(tokenContract))) {
                          tokenContract.withdraw(_amt);
                      }
                      setUint(setId, _amt);
                      _eventName = "LogWithdrawLiquidated(uint256,bytes32,uint256,uint256,uint256)";
                      _eventParam = abi.encode(vault, ilk, _amt, getId, setId);
                  }
                  struct MakerData {
                      uint _vault;
                      address colAddr;
                      TokenJoinInterface tokenJoinContract;
                      VatLike vatContract;
                      TokenInterface tokenContract;
                  }
                  /**
                   * @dev Deposit ETH/ERC20_Token Collateral and Borrow DAI.
                   * @notice Deposit collateral and borrow DAI.
                   * @param vault Vault ID. (Use 0 for last opened vault)
                   * @param depositAmt The amount of tokens to deposit. (For max: `uint256(-1)`)
                   * @param borrowAmt The amount of DAI to borrow.
                   * @param getIdDeposit ID to retrieve depositAmt.
                   * @param getIdBorrow ID to retrieve borrowAmt.
                   * @param setIdDeposit ID stores the amount of tokens deposited.
                   * @param setIdBorrow ID stores the amount of DAI borrowed.
                  */
                  function depositAndBorrow(
                      uint256 vault,
                      uint256 depositAmt,
                      uint256 borrowAmt,
                      uint256 getIdDeposit,
                      uint256 getIdBorrow,
                      uint256 setIdDeposit,
                      uint256 setIdBorrow
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      MakerData memory makerData;
                      uint _amtDeposit = getUint(getIdDeposit, depositAmt);
                      uint _amtBorrow = getUint(getIdBorrow, borrowAmt);
                      makerData._vault = getVault(vault);
                      (bytes32 ilk, address urn) = getVaultData(makerData._vault);
                      makerData.colAddr = instaMapping.gemJoinMapping(ilk);
                      makerData.tokenJoinContract = TokenJoinInterface(makerData.colAddr);
                      makerData.vatContract = VatLike(managerContract.vat());
                      makerData.tokenContract = makerData.tokenJoinContract.gem();
                      if (isEth(address(makerData.tokenContract))) {
                          _amtDeposit = _amtDeposit == uint(-1) ? address(this).balance : _amtDeposit;
                          makerData.tokenContract.deposit{value: _amtDeposit}();
                      } else {
                          _amtDeposit = _amtDeposit == uint(-1) ?  makerData.tokenContract.balanceOf(address(this)) : _amtDeposit;
                      }
                      approve(makerData.tokenContract, address(makerData.colAddr), _amtDeposit);
                      makerData.tokenJoinContract.join(urn, _amtDeposit);
                      managerContract.frob(
                          makerData._vault,
                          toInt(convertTo18(makerData.tokenJoinContract.dec(), _amtDeposit)),
                          _getBorrowAmt(
                              address(makerData.vatContract),
                              urn,
                              ilk,
                              _amtBorrow
                          )
                      );
                      managerContract.move(
                          makerData._vault,
                          address(this),
                          toRad(_amtBorrow)
                      );
                      if (makerData.vatContract.can(address(this), address(daiJoinContract)) == 0) {
                          makerData.vatContract.hope(address(daiJoinContract));
                      }
                      daiJoinContract.exit(address(this), _amtBorrow);
                      setUint(setIdDeposit, _amtDeposit);
                      setUint(setIdBorrow, _amtBorrow);
                      _eventName = "LogDepositAndBorrow(uint256,bytes32,uint256,uint256,uint256,uint256,uint256,uint256)";
                      _eventParam = abi.encode(
                          makerData._vault,
                          ilk,
                          _amtDeposit,
                          _amtBorrow,
                          getIdDeposit,
                          getIdBorrow,
                          setIdDeposit,
                          setIdBorrow
                      );
                  }
                  /**
                   * @dev Exit DAI from urn.
                   * @notice Exit DAI from urn.
                   * @param vault Vault ID. (Use 0 for last opened vault)
                   * @param amt The amount of DAI to exit. (For max: `uint256(-1)`)
                   * @param getId ID to retrieve amt.
                   * @param setId ID stores the amount of DAI exited.
                  */
                  function exitDai(
                      uint256 vault,
                      uint256 amt,
                      uint256 getId,
                      uint256 setId
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      uint _amt = getUint(getId, amt);
                      uint _vault = getVault(vault);
                      (bytes32 ilk, address urn) = getVaultData(_vault);
                      VatLike vatContract = VatLike(managerContract.vat());
                      if(_amt == uint(-1)) {
                          _amt = vatContract.dai(urn);
                          _amt = _amt / 10 ** 27;
                      }
                      managerContract.move(
                          _vault,
                          address(this),
                          toRad(_amt)
                      );
                      if (vatContract.can(address(this), address(daiJoinContract)) == 0) {
                          vatContract.hope(address(daiJoinContract));
                      }
                      daiJoinContract.exit(address(this), _amt);
                      setUint(setId, _amt);
                      _eventName = "LogExitDai(uint256,bytes32,uint256,uint256,uint256)";
                      _eventParam = abi.encode(_vault, ilk, _amt, getId, setId);
                  }
                  /**
                   * @dev Deposit DAI in DSR.
                   * @notice Deposit DAI in DSR.
                   * @param amt The amount of DAI to deposit. (For max: `uint256(-1)`)
                   * @param getId ID to retrieve amt.
                   * @param setId ID stores the amount of DAI deposited.
                  */
                  function depositDai(
                      uint256 amt,
                      uint256 getId,
                      uint256 setId
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      uint _amt = getUint(getId, amt);
                      _amt = _amt == uint(-1) ?
                          daiJoinContract.dai().balanceOf(address(this)) :
                          _amt;
                      VatLike vat = daiJoinContract.vat();
                      uint chi = potContract.drip();
                      approve(daiJoinContract.dai(), address(daiJoinContract), _amt);
                      daiJoinContract.join(address(this), _amt);
                      if (vat.can(address(this), address(potContract)) == 0) {
                          vat.hope(address(potContract));
                      }
                      potContract.join(mul(_amt, RAY) / chi);
                      setUint(setId, _amt);
                      _eventName = "LogDepositDai(uint256,uint256,uint256)";
                      _eventParam = abi.encode(_amt, getId, setId);
                  }
                  /**
                   * @dev Withdraw DAI from DSR.
                   * @notice Withdraw DAI from DSR.
                   * @param amt The amount of DAI to withdraw. (For max: `uint256(-1)`)
                   * @param getId ID to retrieve amt.
                   * @param setId ID stores the amount of DAI withdrawn.
                  */
                  function withdrawDai(
                      uint256 amt,
                      uint256 getId,
                      uint256 setId
                  ) external payable returns (string memory _eventName, bytes memory _eventParam) {
                      uint _amt = getUint(getId, amt);
                      VatLike vat = daiJoinContract.vat();
                      uint chi = potContract.drip();
                      uint pie;
                      if (_amt == uint(-1)) {
                          pie = potContract.pie(address(this));
                          _amt = mul(chi, pie) / RAY;
                      } else {
                          pie = mul(_amt, RAY) / chi;
                      }
                      potContract.exit(pie);
                      uint bal = vat.dai(address(this));
                      if (vat.can(address(this), address(daiJoinContract)) == 0) {
                          vat.hope(address(daiJoinContract));
                      }
                      daiJoinContract.exit(
                          address(this),
                          bal >= mul(_amt, RAY) ? _amt : bal / RAY
                      );
                      setUint(setId, _amt);
                      _eventName = "LogWithdrawDai(uint256,uint256,uint256)";
                      _eventParam = abi.encode(_amt, getId, setId);
                  }
              }
              contract ConnectV2MakerDAO is MakerResolver {
                  string public constant name = "MakerDAO-v1.2";
              }
              pragma solidity ^0.7.0;
              interface TokenInterface {
                  function approve(address, uint256) external;
                  function transfer(address, uint) external;
                  function transferFrom(address, address, uint) external;
                  function deposit() external payable;
                  function withdraw(uint) external;
                  function balanceOf(address) external view returns (uint);
                  function decimals() external view returns (uint);
              }
              interface MemoryInterface {
                  function getUint(uint id) external returns (uint num);
                  function setUint(uint id, uint val) external;
              }
              interface InstaMapping {
                  function cTokenMapping(address) external view returns (address);
                  function gemJoinMapping(bytes32) external view returns (address);
              }
              interface AccountInterface {
                  function enable(address) external;
                  function disable(address) external;
                  function isAuth(address) external view returns (bool);
              }
              pragma solidity ^0.7.0;
              import { DSMath } from "../../common/math.sol";
              import { Basic } from "../../common/basic.sol";
              import { TokenInterface } from "../../common/interfaces.sol";
              import { ManagerLike, DaiJoinInterface, PotLike, VatLike, JugLike } from "./interface.sol";
              abstract contract Helpers is DSMath, Basic {
                  /**
                   * @dev Manager Interface
                   */
                  ManagerLike internal constant managerContract = ManagerLike(0x5ef30b9986345249bc32d8928B7ee64DE9435E39);
                  /**
                   * @dev DAI Join
                   */
                  DaiJoinInterface internal constant daiJoinContract = DaiJoinInterface(0x9759A6Ac90977b93B58547b4A71c78317f391A28);
                  /**
                   * @dev Pot
                   */
                  PotLike internal constant potContract = PotLike(0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7);
                  /**
                   * @dev Maker MCD Jug Address.
                  */
                  JugLike internal constant mcdJug = JugLike(0x19c0976f590D67707E62397C87829d896Dc0f1F1);
                  /**
                   * @dev Return Close Vault Address.
                  */
                  address internal constant giveAddr = 0x4dD58550eb15190a5B3DfAE28BB14EeC181fC267;
                  /**
                   * @dev Get Vault's ilk.
                  */
                  function getVaultData(uint vault) internal view returns (bytes32 ilk, address urn) {
                      ilk = managerContract.ilks(vault);
                      urn = managerContract.urns(vault);
                  }
                  /**
                   * @dev Gem Join address is ETH type collateral.
                  */
                  function isEth(address tknAddr) internal pure returns (bool) {
                      return tknAddr == wethAddr ? true : false;
                  }
                  /**
                   * @dev Get Vault Debt Amount.
                  */
                  function _getVaultDebt(
                      address vat,
                      bytes32 ilk,
                      address urn
                  ) internal view returns (uint wad) {
                      (, uint rate,,,) = VatLike(vat).ilks(ilk);
                      (, uint art) = VatLike(vat).urns(ilk, urn);
                      uint dai = VatLike(vat).dai(urn);
                      uint rad = sub(mul(art, rate), dai);
                      wad = rad / RAY;
                      wad = mul(wad, RAY) < rad ? wad + 1 : wad;
                  }
                  /**
                   * @dev Get Borrow Amount.
                  */
                  function _getBorrowAmt(
                      address vat,
                      address urn,
                      bytes32 ilk,
                      uint amt
                  ) internal returns (int dart)
                  {
                      uint rate = mcdJug.drip(ilk);
                      uint dai = VatLike(vat).dai(urn);
                      if (dai < mul(amt, RAY)) {
                          dart = toInt(sub(mul(amt, RAY), dai) / rate);
                          dart = mul(uint(dart), rate) < mul(amt, RAY) ? dart + 1 : dart;
                      }
                  }
                  /**
                   * @dev Get Payback Amount.
                  */
                  function _getWipeAmt(
                      address vat,
                      uint amt,
                      address urn,
                      bytes32 ilk
                  ) internal view returns (int dart)
                  {
                      (, uint rate,,,) = VatLike(vat).ilks(ilk);
                      (, uint art) = VatLike(vat).urns(ilk, urn);
                      dart = toInt(amt / rate);
                      dart = uint(dart) <= art ? - dart : - toInt(art);
                  }
                  /**
                   * @dev Convert String to bytes32.
                  */
                  function stringToBytes32(string memory str) internal pure returns (bytes32 result) {
                      require(bytes(str).length != 0, "string-empty");
                      // solium-disable-next-line security/no-inline-assembly
                      assembly {
                          result := mload(add(str, 32))
                      }
                  }
                  /**
                   * @dev Get vault ID. If `vault` is 0, get last opened vault.
                  */
                  function getVault(uint vault) internal view returns (uint _vault) {
                      if (vault == 0) {
                          require(managerContract.count(address(this)) > 0, "no-vault-opened");
                          _vault = managerContract.last(address(this));
                      } else {
                          _vault = vault;
                      }
                  }
              }pragma solidity ^0.7.0;
              contract Events {
                  event LogOpen(uint256 indexed vault, bytes32 indexed ilk);
                  event LogClose(uint256 indexed vault, bytes32 indexed ilk);
                  event LogTransfer(uint256 indexed vault, bytes32 indexed ilk, address newOwner);
                  event LogDeposit(uint256 indexed vault, bytes32 indexed ilk, uint256 tokenAmt, uint256 getId, uint256 setId);
                  event LogWithdraw(uint256 indexed vault, bytes32 indexed ilk, uint256 tokenAmt, uint256 getId, uint256 setId);
                  event LogBorrow(uint256 indexed vault, bytes32 indexed ilk, uint256 tokenAmt, uint256 getId, uint256 setId);
                  event LogPayback(uint256 indexed vault, bytes32 indexed ilk, uint256 tokenAmt, uint256 getId, uint256 setId);
                  event LogWithdrawLiquidated(uint256 indexed vault, bytes32 indexed ilk, uint256 tokenAmt, uint256 getId, uint256 setId);
                  event LogExitDai(uint256 indexed vault, bytes32 indexed ilk, uint256 tokenAmt, uint256 getId, uint256 setId);
                  event LogDepositDai(uint256 tokenAmt, uint256 getId, uint256 setId);
                  event LogWithdrawDai(uint256 tokenAmt, uint256 getId, uint256 setId);
                  event LogDepositAndBorrow(
                      uint256 indexed vault,
                      bytes32 indexed ilk,
                      uint256 depositAmt,
                      uint256 borrowAmt,
                      uint256 getIdDeposit,
                      uint256 getIdBorrow,
                      uint256 setIdDeposit,
                      uint256 setIdBorrow
                  );
              }pragma solidity ^0.7.0;
              import { TokenInterface } from "../../common/interfaces.sol";
              interface ManagerLike {
                  function cdpCan(address, uint, address) external view returns (uint);
                  function ilks(uint) external view returns (bytes32);
                  function last(address) external view returns (uint);
                  function count(address) external view returns (uint);
                  function owns(uint) external view returns (address);
                  function urns(uint) external view returns (address);
                  function vat() external view returns (address);
                  function open(bytes32, address) external returns (uint);
                  function give(uint, address) external;
                  function frob(uint, int, int) external;
                  function flux(uint, address, uint) external;
                  function move(uint, address, uint) external;
              }
              interface VatLike {
                  function can(address, address) external view returns (uint);
                  function ilks(bytes32) external view returns (uint, uint, uint, uint, uint);
                  function dai(address) external view returns (uint);
                  function urns(bytes32, address) external view returns (uint, uint);
                  function frob(
                      bytes32,
                      address,
                      address,
                      address,
                      int,
                      int
                  ) external;
                  function hope(address) external;
                  function move(address, address, uint) external;
                  function gem(bytes32, address) external view returns (uint);
              }
              interface TokenJoinInterface {
                  function dec() external returns (uint);
                  function gem() external returns (TokenInterface);
                  function join(address, uint) external payable;
                  function exit(address, uint) external;
              }
              interface DaiJoinInterface {
                  function vat() external returns (VatLike);
                  function dai() external returns (TokenInterface);
                  function join(address, uint) external payable;
                  function exit(address, uint) external;
              }
              interface JugLike {
                  function drip(bytes32) external returns (uint);
              }
              interface PotLike {
                  function pie(address) external view returns (uint);
                  function drip() external returns (uint);
                  function join(uint) external;
                  function exit(uint) external;
              }
              pragma solidity ^0.7.0;
              import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
              contract DSMath {
                uint constant WAD = 10 ** 18;
                uint constant RAY = 10 ** 27;
                function add(uint x, uint y) internal pure returns (uint z) {
                  z = SafeMath.add(x, y);
                }
                function sub(uint x, uint y) internal virtual pure returns (uint z) {
                  z = SafeMath.sub(x, y);
                }
                function mul(uint x, uint y) internal pure returns (uint z) {
                  z = SafeMath.mul(x, y);
                }
                function div(uint x, uint y) internal pure returns (uint z) {
                  z = SafeMath.div(x, y);
                }
                function wmul(uint x, uint y) internal pure returns (uint z) {
                  z = SafeMath.add(SafeMath.mul(x, y), WAD / 2) / WAD;
                }
                function wdiv(uint x, uint y) internal pure returns (uint z) {
                  z = SafeMath.add(SafeMath.mul(x, WAD), y / 2) / y;
                }
                function rdiv(uint x, uint y) internal pure returns (uint z) {
                  z = SafeMath.add(SafeMath.mul(x, RAY), y / 2) / y;
                }
                function rmul(uint x, uint y) internal pure returns (uint z) {
                  z = SafeMath.add(SafeMath.mul(x, y), RAY / 2) / RAY;
                }
                function toInt(uint x) internal pure returns (int y) {
                  y = int(x);
                  require(y >= 0, "int-overflow");
                }
                function toRad(uint wad) internal pure returns (uint rad) {
                  rad = mul(wad, 10 ** 27);
                }
              }
              pragma solidity ^0.7.0;
              import { TokenInterface } from "./interfaces.sol";
              import { Stores } from "./stores.sol";
              import { DSMath } from "./math.sol";
              abstract contract Basic is DSMath, Stores {
                  function convert18ToDec(uint _dec, uint256 _amt) internal pure returns (uint256 amt) {
                      amt = (_amt / 10 ** (18 - _dec));
                  }
                  function convertTo18(uint _dec, uint256 _amt) internal pure returns (uint256 amt) {
                      amt = mul(_amt, 10 ** (18 - _dec));
                  }
                  function getTokenBal(TokenInterface token) internal view returns(uint _amt) {
                      _amt = address(token) == ethAddr ? address(this).balance : token.balanceOf(address(this));
                  }
                  function getTokensDec(TokenInterface buyAddr, TokenInterface sellAddr) internal view returns(uint buyDec, uint sellDec) {
                      buyDec = address(buyAddr) == ethAddr ?  18 : buyAddr.decimals();
                      sellDec = address(sellAddr) == ethAddr ?  18 : sellAddr.decimals();
                  }
                  function encodeEvent(string memory eventName, bytes memory eventParam) internal pure returns (bytes memory) {
                      return abi.encode(eventName, eventParam);
                  }
                  function approve(TokenInterface token, address spender, uint256 amount) internal {
                      try token.approve(spender, amount) {
                      } catch {
                          token.approve(spender, 0);
                          token.approve(spender, amount);
                      }
                  }
                  function changeEthAddress(address buy, address sell) internal pure returns(TokenInterface _buy, TokenInterface _sell){
                      _buy = buy == ethAddr ? TokenInterface(wethAddr) : TokenInterface(buy);
                      _sell = sell == ethAddr ? TokenInterface(wethAddr) : TokenInterface(sell);
                  }
                  function convertEthToWeth(bool isEth, TokenInterface token, uint amount) internal {
                      if(isEth) token.deposit{value: amount}();
                  }
                  function convertWethToEth(bool isEth, TokenInterface token, uint amount) internal {
                     if(isEth) {
                          approve(token, address(token), amount);
                          token.withdraw(amount);
                      }
                  }
              }
              // SPDX-License-Identifier: MIT
              pragma solidity >=0.6.0 <0.8.0;
              /**
               * @dev Wrappers over Solidity's arithmetic operations with added overflow
               * checks.
               *
               * Arithmetic operations in Solidity wrap on overflow. This can easily result
               * in bugs, because programmers usually assume that an overflow raises an
               * error, which is the standard behavior in high level programming languages.
               * `SafeMath` restores this intuition by reverting the transaction when an
               * operation overflows.
               *
               * Using this library instead of the unchecked operations eliminates an entire
               * class of bugs, so it's recommended to use it always.
               */
              library SafeMath {
                  /**
                   * @dev Returns the addition of two unsigned integers, with an overflow flag.
                   *
                   * _Available since v3.4._
                   */
                  function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
                      uint256 c = a + b;
                      if (c < a) return (false, 0);
                      return (true, c);
                  }
                  /**
                   * @dev Returns the substraction of two unsigned integers, with an overflow flag.
                   *
                   * _Available since v3.4._
                   */
                  function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
                      if (b > a) return (false, 0);
                      return (true, a - b);
                  }
                  /**
                   * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
                   *
                   * _Available since v3.4._
                   */
                  function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
                      // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
                      // benefit is lost if 'b' is also tested.
                      // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
                      if (a == 0) return (true, 0);
                      uint256 c = a * b;
                      if (c / a != b) return (false, 0);
                      return (true, c);
                  }
                  /**
                   * @dev Returns the division of two unsigned integers, with a division by zero flag.
                   *
                   * _Available since v3.4._
                   */
                  function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
                      if (b == 0) return (false, 0);
                      return (true, a / b);
                  }
                  /**
                   * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
                   *
                   * _Available since v3.4._
                   */
                  function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
                      if (b == 0) return (false, 0);
                      return (true, a % b);
                  }
                  /**
                   * @dev Returns the addition of two unsigned integers, reverting on
                   * overflow.
                   *
                   * Counterpart to Solidity's `+` operator.
                   *
                   * Requirements:
                   *
                   * - Addition cannot overflow.
                   */
                  function add(uint256 a, uint256 b) internal pure returns (uint256) {
                      uint256 c = a + b;
                      require(c >= a, "SafeMath: addition overflow");
                      return c;
                  }
                  /**
                   * @dev Returns the subtraction of two unsigned integers, reverting on
                   * overflow (when the result is negative).
                   *
                   * Counterpart to Solidity's `-` operator.
                   *
                   * Requirements:
                   *
                   * - Subtraction cannot overflow.
                   */
                  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                      require(b <= a, "SafeMath: subtraction overflow");
                      return a - b;
                  }
                  /**
                   * @dev Returns the multiplication of two unsigned integers, reverting on
                   * overflow.
                   *
                   * Counterpart to Solidity's `*` operator.
                   *
                   * Requirements:
                   *
                   * - Multiplication cannot overflow.
                   */
                  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                      if (a == 0) return 0;
                      uint256 c = a * b;
                      require(c / a == b, "SafeMath: multiplication overflow");
                      return c;
                  }
                  /**
                   * @dev Returns the integer division of two unsigned integers, reverting on
                   * division by zero. The result is rounded towards zero.
                   *
                   * Counterpart to Solidity's `/` operator. Note: this function uses a
                   * `revert` opcode (which leaves remaining gas untouched) while Solidity
                   * uses an invalid opcode to revert (consuming all remaining gas).
                   *
                   * Requirements:
                   *
                   * - The divisor cannot be zero.
                   */
                  function div(uint256 a, uint256 b) internal pure returns (uint256) {
                      require(b > 0, "SafeMath: division by zero");
                      return a / b;
                  }
                  /**
                   * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
                   * reverting when dividing by zero.
                   *
                   * Counterpart to Solidity's `%` operator. This function uses a `revert`
                   * opcode (which leaves remaining gas untouched) while Solidity uses an
                   * invalid opcode to revert (consuming all remaining gas).
                   *
                   * Requirements:
                   *
                   * - The divisor cannot be zero.
                   */
                  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                      require(b > 0, "SafeMath: modulo by zero");
                      return a % b;
                  }
                  /**
                   * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
                   * overflow (when the result is negative).
                   *
                   * CAUTION: This function is deprecated because it requires allocating memory for the error
                   * message unnecessarily. For custom revert reasons use {trySub}.
                   *
                   * Counterpart to Solidity's `-` operator.
                   *
                   * Requirements:
                   *
                   * - Subtraction cannot overflow.
                   */
                  function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                      require(b <= a, errorMessage);
                      return a - b;
                  }
                  /**
                   * @dev Returns the integer division of two unsigned integers, reverting with custom message on
                   * division by zero. The result is rounded towards zero.
                   *
                   * CAUTION: This function is deprecated because it requires allocating memory for the error
                   * message unnecessarily. For custom revert reasons use {tryDiv}.
                   *
                   * Counterpart to Solidity's `/` operator. Note: this function uses a
                   * `revert` opcode (which leaves remaining gas untouched) while Solidity
                   * uses an invalid opcode to revert (consuming all remaining gas).
                   *
                   * Requirements:
                   *
                   * - The divisor cannot be zero.
                   */
                  function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                      require(b > 0, errorMessage);
                      return a / b;
                  }
                  /**
                   * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
                   * reverting with custom message when dividing by zero.
                   *
                   * CAUTION: This function is deprecated because it requires allocating memory for the error
                   * message unnecessarily. For custom revert reasons use {tryMod}.
                   *
                   * Counterpart to Solidity's `%` operator. This function uses a `revert`
                   * opcode (which leaves remaining gas untouched) while Solidity uses an
                   * invalid opcode to revert (consuming all remaining gas).
                   *
                   * Requirements:
                   *
                   * - The divisor cannot be zero.
                   */
                  function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                      require(b > 0, errorMessage);
                      return a % b;
                  }
              }
              pragma solidity ^0.7.0;
              import { MemoryInterface, InstaMapping } from "./interfaces.sol";
              abstract contract Stores {
                /**
                 * @dev Return ethereum address
                 */
                address constant internal ethAddr = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
                /**
                 * @dev Return Wrapped ETH address
                 */
                address constant internal wethAddr = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
                /**
                 * @dev Return memory variable address
                 */
                MemoryInterface constant internal instaMemory = MemoryInterface(0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F);
                /**
                 * @dev Return InstaDApp Mapping Addresses
                 */
                InstaMapping constant internal instaMapping = InstaMapping(0xe81F70Cc7C0D46e12d70efc60607F16bbD617E88);
                /**
                 * @dev Get Uint value from InstaMemory Contract.
                 */
                function getUint(uint getId, uint val) internal returns (uint returnVal) {
                  returnVal = getId == 0 ? val : instaMemory.getUint(getId);
                }
                /**
                * @dev Set Uint value in InstaMemory Contract.
                */
                function setUint(uint setId, uint val) virtual internal {
                  if (setId != 0) instaMemory.setUint(setId, val);
                }
              }