ETH Price: $2,965.91 (-6.09%)
Gas: 20 Gwei

Transaction Decoder

Block:
9062350 at Dec-06-2019 08:28:41 PM +UTC
Transaction Fee:
0.001919616 ETH $5.69
Gas Used:
239,952 Gas / 8 Gwei

Emitted Events:

34 DSPause.0x46d2fbbb00000000000000000000000000000000000000000000000000000000( 0x46d2fbbb00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000f267efdda842539a2caff990259395188a86b813, 0x000000000000000000000000a220eaa2cc130d076c57e6067d9baeaa7261f200, 0xeb3228cebf021035c6fd6550c6fc1d638885659fee291dc5711e046bfd9f3b64, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000040, 00000000000000000000000000000000000000000000000000000000000000c4, 46d2fbbb000000000000000000000000a220eaa2cc130d076c57e6067d9baeaa, 7261f200eb3228cebf021035c6fd6550c6fc1d638885659fee291dc5711e046b, fd9f3b6400000000000000000000000000000000000000000000000000000000, 0000008000000000000000000000000000000000000000000000000000000000, 5deab9f900000000000000000000000000000000000000000000000000000000, 0000000461461954000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
35 DSPause.0x168ccd6700000000000000000000000000000000000000000000000000000000( 0x168ccd6700000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000f267efdda842539a2caff990259395188a86b813, 0x000000000000000000000000a220eaa2cc130d076c57e6067d9baeaa7261f200, 0xeb3228cebf021035c6fd6550c6fc1d638885659fee291dc5711e046bfd9f3b64, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000040, 00000000000000000000000000000000000000000000000000000000000000c4, 168ccd67000000000000000000000000a220eaa2cc130d076c57e6067d9baeaa, 7261f200eb3228cebf021035c6fd6550c6fc1d638885659fee291dc5711e046b, fd9f3b6400000000000000000000000000000000000000000000000000000000, 0000008000000000000000000000000000000000000000000000000000000000, 5deab9f900000000000000000000000000000000000000000000000000000000, 0000000461461954000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
36 Vat.0x29ae811400000000000000000000000000000000000000000000000000000000( 0x29ae811400000000000000000000000000000000000000000000000000000000, 0x4c696e6500000000000000000000000000000000000000000000000000000000, 0x00000000000000000001dbc08ad4cb4df0e8657af43474113b50000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, 29ae81144c696e65000000000000000000000000000000000000000000000000, 0000000000000000000000000001dbc08ad4cb4df0e8657af43474113b500000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
37 Vat.0x1a0b287e00000000000000000000000000000000000000000000000000000000( 0x1a0b287e00000000000000000000000000000000000000000000000000000000, 0x4554482d41000000000000000000000000000000000000000000000000000000, 0x6c696e6500000000000000000000000000000000000000000000000000000000, 0x00000000000000000000c875151a612ae861eb7a47413f496af8000000000000, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, 1a0b287e4554482d410000000000000000000000000000000000000000000000, 000000006c696e65000000000000000000000000000000000000000000000000, 0000000000000000000000000000c875151a612ae861eb7a47413f496af80000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
38 Vat.0xf24e23eb00000000000000000000000000000000000000000000000000000000( 0xf24e23eb00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000a950524441892a31ebddf91d3ceefa04bf454466, 0x000000000000000000000000197e90f9fad81970ba7976f33cbd77088e5d7cf7, 0x000000000000000000000000004bb58b7e16e36442909d200caf99b78b8fac26, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, f24e23eb000000000000000000000000a950524441892a31ebddf91d3ceefa04, bf454466000000000000000000000000197e90f9fad81970ba7976f33cbd7708, 8e5d7cf7000000000000000000000000004bb58b7e16e36442909d200caf99b7, 8b8fac2600000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
39 Pot.0x9f678cca00000000000000000000000000000000000000000000000000000000( 0x9f678cca00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000be8e3e3618f7474f8cb1d074a26affef007e98fb, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, 9f678cca00000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
40 Pot.0x29ae811400000000000000000000000000000000000000000000000000000000( 0x29ae811400000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000be8e3e3618f7474f8cb1d074a26affef007e98fb, 0x6473720000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000033b2e3cb112f1349de86fd8, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, 29ae811464737200000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000033b2e3cb112f134, 9de86fd800000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
41 SaiMom.0x47786d3700000000000000000000000000000000000000000000000000000000( 0x47786d3700000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000f267efdda842539a2caff990259395188a86b813, 0x0000000000000000000000000000000000000000004e950851be0c2ebf000000, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 0000000000000000000000000000000000000000000000000000002447786d37, 0000000000000000000000000000000000000000004e950851be0c2ebf000000 )
42 SaiTub.0x92b0d72100000000000000000000000000000000000000000000000000000000( 0x92b0d72100000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000f2c5369cffb8ea6284452b0326e326dbfdcb867c, 0x6361700000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000004e950851be0c2ebf000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 0000000000000000000000000000000000000000000000000000004492b0d721, 6361700000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000004e950851be0c2ebf000000 )
43 SaiMom.0x69fe0e2d00000000000000000000000000000000000000000000000000000000( 0x69fe0e2d00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000f267efdda842539a2caff990259395188a86b813, 0x0000000000000000000000000000000000000000033b2e3cacd278c7503e82c1, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 0000000000000000000000000000000000000000000000000000002469fe0e2d, 0000000000000000000000000000000000000000033b2e3cacd278c7503e82c1 )
44 SaiTub.0x92b0d72100000000000000000000000000000000000000000000000000000000( 0x92b0d72100000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000f2c5369cffb8ea6284452b0326e326dbfdcb867c, 0x6665650000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000033b2e3cacd278c7503e82c1, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 0000000000000000000000000000000000000000000000000000004492b0d721, 6665650000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000033b2e3cacd278c7503e82c1 )
45 SaiTub.0x92b0d72100000000000000000000000000000000000000000000000000000000( 0x92b0d72100000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000f2c5369cffb8ea6284452b0326e326dbfdcb867c, 0x6665650000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000033b2e3cacd278c7503e82c1, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 0000000000000000000000000000000000000000000000000000004492b0d721, 6665650000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000033b2e3cacd278c7503e82c1 )

Account State Difference:

  Address   Before After State Difference Code
0x197E90f9...88E5D7cf7
(Maker: MCD Pot)
0x35D1b3F3...259A0492B
(Maker: MCD Vat)
0x448a5065...040f59af3
(Maker: Contract 1)
(Spark Pool)
71.157116635339863948 Eth71.159036251339863948 Eth0.001919616
0xB8bBf36b...9fFFBa604
0.542017876534879824 Eth
Nonce: 162
0.540098260534879824 Eth
Nonce: 163
0.001919616
0xF267EFDD...88a86b813

Execution Trace

DssDecember6Spell.CALL( )
  • DSPause.plot( usr=0xA220Eaa2Cc130D076c57e6067D9baEaA7261F200, tag=EB3228CEBF021035C6FD6550C6FC1D638885659FEE291DC5711E046BFD9F3B64, fax=0x61461954, eta=1575664121 )
    • DSChief.canCall( caller=0xF267EFDDA842539a2cAff990259395188a86b813, code=0xbE286431454714F511008713973d3B053A2d38f3, sig=System.Byte[] ) => ( True )
    • DSPause.exec( usr=0xA220Eaa2Cc130D076c57e6067D9baEaA7261F200, tag=EB3228CEBF021035C6FD6550C6FC1D638885659FEE291DC5711E046BFD9F3B64, fax=0x61461954, eta=1575664121 ) => ( out=0x )
      • DSPauseProxy.exec( usr=0xA220Eaa2Cc130D076c57e6067D9baEaA7261F200, fax=0x61461954 ) => ( out=0x )
        • 0xa220eaa2cc130d076c57e6067d9baeaa7261f200.DELEGATECALL( )
          • Vat.file( what=4C696E6500000000000000000000000000000000000000000000000000000000, data=178000000000000000000000000000000000000000000000000000 )
          • Vat.file( ilk=4554482D41000000000000000000000000000000000000000000000000000000, what=6C696E6500000000000000000000000000000000000000000000000000000000, data=75000000000000000000000000000000000000000000000000000 )
          • Pot.CALL( )
            • Vat.suck( u=0xA950524441892A31ebddF91d3cEEFa04Bf454466, v=0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7, rad=1688370680494017400888923723637394728555621414 )
            • Pot.file( what=6473720000000000000000000000000000000000000000000000000000000000, data=1000000001243680656318820312 )
            • DSPauseProxy.STATICCALL( )
            • SaiMom.setCap( wad=95000000000000000000000000 )
              • DSChief.canCall( caller=0xF267EFDDA842539a2cAff990259395188a86b813, code=0xF2C5369cFFb8Ea6284452b0326e326DbFdCb867C, sig=System.Byte[] ) => ( True )
              • SaiTub.mold( param=6361700000000000000000000000000000000000000000000000000000000000, val=95000000000000000000000000 )
                • DSGuard.canCall( src_=0xF2C5369cFFb8Ea6284452b0326e326DbFdCb867C, dst_=0x448a5065aeBB8E423F0896E6c5D525C040f59af3, sig=System.Byte[] ) => ( True )
                • SaiMom.setFee( ray=1000000000937303470807876289 )
                  • DSChief.canCall( caller=0xF267EFDDA842539a2cAff990259395188a86b813, code=0xF2C5369cFFb8Ea6284452b0326e326DbFdCb867C, sig=System.Byte[] ) => ( True )
                  • SaiTub.mold( param=6665650000000000000000000000000000000000000000000000000000000000, val=1000000000937303470807876289 )
                    • DSGuard.canCall( src_=0xF2C5369cFFb8Ea6284452b0326e326DbFdCb867C, dst_=0x448a5065aeBB8E423F0896E6c5D525C040f59af3, sig=System.Byte[] ) => ( True )
                    • SaiTub.CALL( )
                      File 1 of 9: DssDecember6Spell
                      pragma solidity 0.5.12;
                      
                      contract FileLike {
                          function file(bytes32, uint256) external;
                          function file(bytes32, bytes32, uint256) external;
                      }
                      
                      contract JugLike {
                          function drip(bytes32) external;
                          function file(bytes32, bytes32, uint256) external;
                      }
                      
                      contract PotLike {
                          function drip() external;
                          function file(bytes32, uint256) external;
                      }
                      
                      contract PauseLike {
                          function delay() external view returns (uint256);
                          function plot(address, bytes32, bytes calldata, uint256) external;
                          function exec(address, bytes32, bytes calldata, uint256) external;
                      }
                      
                      contract MomLike {
                          function setCap(uint256) external;
                          function setFee(uint256) external;
                      }
                      
                      contract DssFlopReplaceSpellAction {
                          uint256 constant RAD = 10 ** 45;
                          address constant public VAT = 0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B;
                          address constant public JUG = 0x19c0976f590D67707E62397C87829d896Dc0f1F1;
                          address constant public POT = 0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7;
                      
                          function execute() external {
                              // set the global debt ceiling to 178,000,000
                              FileLike(VAT).file("Line", 178000000 * RAD);
                      
                              // set the ETH-A debt ceiling to 75,000,000
                              FileLike(VAT).file("ETH-A", "line", 75000000 * RAD);
                      
                              // DSR
                              PotLike(POT).drip();
                              PotLike(POT).file("dsr", 1000000001243680656318820312);
                      
                              // drip
                              // JugLike(JUG).drip("ETH-A");
                              // JugLike(JUG).drip("BAT-A");
                      
                              // set ETH-A duty to X
                              // JugLike(JUG).file("ETH-A", "duty", X);
                      
                              // set BAT-A duty to X
                              // JugLike(JUG).file("BAT-A", "duty", X);
                          }
                      }
                      
                      contract DssDecember6Spell {
                          PauseLike public pause =
                              PauseLike(0xbE286431454714F511008713973d3B053A2d38f3);
                          address constant public SAIMOM = 0xF2C5369cFFb8Ea6284452b0326e326DbFdCb867C;
                          uint256 constant public SCDCAP = 95000000 * 10 ** 18;
                          uint256 constant public NEWFEE = 1000000000937303470807876289;
                          address   public action;
                          bytes32   public tag;
                          uint256   public eta;
                          bytes     public sig;
                          bool      public done;
                      
                          constructor() public {
                              sig = abi.encodeWithSignature("execute()");
                              action = address(new DssFlopReplaceSpellAction());
                              bytes32 _tag;
                              address _action = action;
                              assembly { _tag := extcodehash(_action) }
                              tag = _tag;
                          }
                      
                          function cast() external {
                              require(!done, "spell-already-cast");
                              done = true;
                              pause.plot(action, tag, sig, now);
                              pause.exec(action, tag, sig, now);
                              // Lower Debt Ceiling in SCD to 95,000,000
                              MomLike(SAIMOM).setCap(SCDCAP);
                              MomLike(SAIMOM).setFee(NEWFEE);
                          }
                      }

                      File 2 of 9: DSPause
                      // hevm: flattened sources of /nix/store/b2bvh9ljr3yljrdz6lm764hdyj7nk4iy-ds-pause-f43edc1/src/pause.sol
                      pragma solidity >=0.4.23 >=0.5.0 <0.6.0;
                      
                      ////// /nix/store/6qq1ps6wrikrl6ha3q33739dbs2wg2hb-ds-note/dapp/ds-note/src/note.sol
                      /// note.sol -- the `note' modifier, for logging calls as events
                      
                      // 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.4.23; */
                      
                      contract DSNote {
                          event LogNote(
                              bytes4   indexed  sig,
                              address  indexed  guy,
                              bytes32  indexed  foo,
                              bytes32  indexed  bar,
                              uint256           wad,
                              bytes             fax
                          ) anonymous;
                      
                          modifier note {
                              bytes32 foo;
                              bytes32 bar;
                              uint256 wad;
                      
                              assembly {
                                  foo := calldataload(4)
                                  bar := calldataload(36)
                                  wad := callvalue
                              }
                      
                              emit LogNote(msg.sig, msg.sender, foo, bar, wad, msg.data);
                      
                              _;
                          }
                      }
                      
                      ////// /nix/store/r1w3fgb8wh0c2qn0i8jg95sv99l5nh7j-ds-auth/dapp/ds-auth/src/auth.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.4.23; */
                      
                      contract DSAuthority {
                          function canCall(
                              address src, address dst, bytes4 sig
                          ) public view returns (bool);
                      }
                      
                      contract DSAuthEvents {
                          event LogSetAuthority (address indexed authority);
                          event LogSetOwner     (address indexed owner);
                      }
                      
                      contract DSAuth is DSAuthEvents {
                          DSAuthority  public  authority;
                          address      public  owner;
                      
                          constructor() public {
                              owner = msg.sender;
                              emit LogSetOwner(msg.sender);
                          }
                      
                          function setOwner(address owner_)
                              public
                              auth
                          {
                              owner = owner_;
                              emit LogSetOwner(owner);
                          }
                      
                          function setAuthority(DSAuthority authority_)
                              public
                              auth
                          {
                              authority = authority_;
                              emit LogSetAuthority(address(authority));
                          }
                      
                          modifier auth {
                              require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized");
                              _;
                          }
                      
                          function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
                              if (src == address(this)) {
                                  return true;
                              } else if (src == owner) {
                                  return true;
                              } else if (authority == DSAuthority(0)) {
                                  return false;
                              } else {
                                  return authority.canCall(src, address(this), sig);
                              }
                          }
                      }
                      
                      ////// /nix/store/b2bvh9ljr3yljrdz6lm764hdyj7nk4iy-ds-pause-f43edc1/src/pause.sol
                      // Copyright (C) 2019 David Terry <[email protected]>
                      //
                      // 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.0 <0.6.0; */
                      
                      /* import {DSNote} from "ds-note/note.sol"; */
                      /* import {DSAuth, DSAuthority} from "ds-auth/auth.sol"; */
                      
                      contract DSPause is DSAuth, DSNote {
                      
                          // --- admin ---
                      
                          modifier wait { require(msg.sender == address(proxy), "ds-pause-undelayed-call"); _; }
                      
                          function setOwner(address owner_) public wait {
                              owner = owner_;
                              emit LogSetOwner(owner);
                          }
                          function setAuthority(DSAuthority authority_) public wait {
                              authority = authority_;
                              emit LogSetAuthority(address(authority));
                          }
                          function setDelay(uint delay_) public note wait {
                              delay = delay_;
                          }
                      
                          // --- math ---
                      
                          function add(uint x, uint y) internal pure returns (uint z) {
                              z = x + y;
                              require(z >= x, "ds-pause-addition-overflow");
                          }
                      
                          // --- data ---
                      
                          mapping (bytes32 => bool) public plans;
                          DSPauseProxy public proxy;
                          uint         public delay;
                      
                          // --- init ---
                      
                          constructor(uint delay_, address owner_, DSAuthority authority_) public {
                              delay = delay_;
                              owner = owner_;
                              authority = authority_;
                              proxy = new DSPauseProxy();
                          }
                      
                          // --- util ---
                      
                          function hash(address usr, bytes32 tag, bytes memory fax, uint eta)
                              internal pure
                              returns (bytes32)
                          {
                              return keccak256(abi.encode(usr, tag, fax, eta));
                          }
                      
                          function soul(address usr)
                              internal view
                              returns (bytes32 tag)
                          {
                              assembly { tag := extcodehash(usr) }
                          }
                      
                          // --- operations ---
                      
                          function plot(address usr, bytes32 tag, bytes memory fax, uint eta)
                              public note auth
                          {
                              require(eta >= add(now, delay), "ds-pause-delay-not-respected");
                              plans[hash(usr, tag, fax, eta)] = true;
                          }
                      
                          function drop(address usr, bytes32 tag, bytes memory fax, uint eta)
                              public note auth
                          {
                              plans[hash(usr, tag, fax, eta)] = false;
                          }
                      
                          function exec(address usr, bytes32 tag, bytes memory fax, uint eta)
                              public note
                              returns (bytes memory out)
                          {
                              require(plans[hash(usr, tag, fax, eta)], "ds-pause-unplotted-plan");
                              require(soul(usr) == tag,                "ds-pause-wrong-codehash");
                              require(now >= eta,                      "ds-pause-premature-exec");
                      
                              plans[hash(usr, tag, fax, eta)] = false;
                      
                              out = proxy.exec(usr, fax);
                              require(proxy.owner() == address(this), "ds-pause-illegal-storage-change");
                          }
                      }
                      
                      // plans are executed in an isolated storage context to protect the pause from
                      // malicious storage modification during plan execution
                      contract DSPauseProxy {
                          address public owner;
                          modifier auth { require(msg.sender == owner, "ds-pause-proxy-unauthorized"); _; }
                          constructor() public { owner = msg.sender; }
                      
                          function exec(address usr, bytes memory fax)
                              public auth
                              returns (bytes memory out)
                          {
                              bool ok;
                              (ok, out) = usr.delegatecall(fax);
                              require(ok, "ds-pause-delegatecall-error");
                          }
                      }

                      File 3 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 <[email protected]>
                      //
                      // 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 4 of 9: Pot
                      // hevm: flattened sources of /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/pot.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/pot.sol
                      /// pot.sol -- Dai Savings Rate
                      
                      // Copyright (C) 2018 Rain <[email protected]>
                      //
                      // 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"; */
                      
                      /*
                         "Savings Dai" is obtained when Dai is deposited into
                         this contract. Each "Savings Dai" accrues Dai interest
                         at the "Dai Savings Rate".
                      
                         This contract does not implement a user tradeable token
                         and is intended to be used with adapters.
                      
                               --- `save` your `dai` in the `pot` ---
                      
                         - `dsr`: the Dai Savings Rate
                         - `pie`: user balance of Savings Dai
                      
                         - `join`: start saving some dai
                         - `exit`: remove some dai
                         - `drip`: perform rate collection
                      
                      */
                      
                      contract VatLike {
                          function move(address,address,uint256) external;
                          function suck(address,address,uint256) external;
                      }
                      
                      contract Pot 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, "Pot/not-authorized");
                              _;
                          }
                      
                          // --- Data ---
                          mapping (address => uint256) public pie;  // user Savings Dai
                      
                          uint256 public Pie;  // total Savings Dai
                          uint256 public dsr;  // the Dai Savings Rate
                          uint256 public chi;  // the Rate Accumulator
                      
                          VatLike public vat;  // CDP engine
                          address public vow;  // debt engine
                          uint256 public rho;  // time of last drip
                      
                          uint256 public live;  // Access Flag
                      
                          // --- Init ---
                          constructor(address vat_) public {
                              wards[msg.sender] = 1;
                              vat = VatLike(vat_);
                              dsr = ONE;
                              chi = ONE;
                              rho = now;
                              live = 1;
                          }
                      
                          // --- Math ---
                          uint256 constant ONE = 10 ** 27;
                          function rpow(uint x, uint n, uint base) internal pure returns (uint z) {
                              assembly {
                                  switch x case 0 {switch n case 0 {z := base} default {z := 0}}
                                  default {
                                      switch mod(n, 2) case 0 { z := base } default { z := x }
                                      let half := div(base, 2)  // for rounding.
                                      for { n := div(n, 2) } n { n := div(n,2) } {
                                          let xx := mul(x, x)
                                          if iszero(eq(div(xx, x), x)) { revert(0,0) }
                                          let xxRound := add(xx, half)
                                          if lt(xxRound, xx) { revert(0,0) }
                                          x := div(xxRound, base)
                                          if mod(n,2) {
                                              let zx := mul(z, x)
                                              if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
                                              let zxRound := add(zx, half)
                                              if lt(zxRound, zx) { revert(0,0) }
                                              z := div(zxRound, base)
                                          }
                                      }
                                  }
                              }
                          }
                      
                          function rmul(uint x, uint y) internal pure returns (uint z) {
                              z = mul(x, y) / ONE;
                          }
                      
                          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 file(bytes32 what, uint256 data) external note auth {
                              require(live == 1, "Pot/not-live");
                              require(now == rho, "Pot/rho-not-updated");
                              if (what == "dsr") dsr = data;
                              else revert("Pot/file-unrecognized-param");
                          }
                      
                          function file(bytes32 what, address addr) external note auth {
                              if (what == "vow") vow = addr;
                              else revert("Pot/file-unrecognized-param");
                          }
                      
                          function cage() external note auth {
                              live = 0;
                              dsr = ONE;
                          }
                      
                          // --- Savings Rate Accumulation ---
                          function drip() external note returns (uint tmp) {
                              require(now >= rho, "Pot/invalid-now");
                              tmp = rmul(rpow(dsr, now - rho, ONE), chi);
                              uint chi_ = sub(tmp, chi);
                              chi = tmp;
                              rho = now;
                              vat.suck(address(vow), address(this), mul(Pie, chi_));
                          }
                      
                          // --- Savings Dai Management ---
                          function join(uint wad) external note {
                              require(now == rho, "Pot/rho-not-updated");
                              pie[msg.sender] = add(pie[msg.sender], wad);
                              Pie             = add(Pie,             wad);
                              vat.move(msg.sender, address(this), mul(chi, wad));
                          }
                      
                          function exit(uint wad) external note {
                              pie[msg.sender] = sub(pie[msg.sender], wad);
                              Pie             = sub(Pie,             wad);
                              vat.move(address(this), msg.sender, mul(chi, wad));
                          }
                      }

                      File 5 of 9: SaiMom
                      // hevm: flattened sources of src/mom.sol
                      pragma solidity ^0.4.18;
                      
                      ////// lib/ds-guard/lib/ds-auth/src/auth.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.4.13; */
                      
                      contract DSAuthority {
                          function canCall(
                              address src, address dst, bytes4 sig
                          ) public view returns (bool);
                      }
                      
                      contract DSAuthEvents {
                          event LogSetAuthority (address indexed authority);
                          event LogSetOwner     (address indexed owner);
                      }
                      
                      contract DSAuth is DSAuthEvents {
                          DSAuthority  public  authority;
                          address      public  owner;
                      
                          function DSAuth() public {
                              owner = msg.sender;
                              LogSetOwner(msg.sender);
                          }
                      
                          function setOwner(address owner_)
                              public
                              auth
                          {
                              owner = owner_;
                              LogSetOwner(owner);
                          }
                      
                          function setAuthority(DSAuthority authority_)
                              public
                              auth
                          {
                              authority = authority_;
                              LogSetAuthority(authority);
                          }
                      
                          modifier auth {
                              require(isAuthorized(msg.sender, msg.sig));
                              _;
                          }
                      
                          function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
                              if (src == address(this)) {
                                  return true;
                              } else if (src == owner) {
                                  return true;
                              } else if (authority == DSAuthority(0)) {
                                  return false;
                              } else {
                                  return authority.canCall(src, this, sig);
                              }
                          }
                      }
                      
                      ////// lib/ds-spell/lib/ds-note/src/note.sol
                      /// note.sol -- the `note' modifier, for logging calls as events
                      
                      // 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.4.13; */
                      
                      contract DSNote {
                          event LogNote(
                              bytes4   indexed  sig,
                              address  indexed  guy,
                              bytes32  indexed  foo,
                              bytes32  indexed  bar,
                              uint              wad,
                              bytes             fax
                          ) anonymous;
                      
                          modifier note {
                              bytes32 foo;
                              bytes32 bar;
                      
                              assembly {
                                  foo := calldataload(4)
                                  bar := calldataload(36)
                              }
                      
                              LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);
                      
                              _;
                          }
                      }
                      
                      ////// lib/ds-thing/lib/ds-math/src/math.sol
                      /// math.sol -- mixin for inline numerical wizardry
                      
                      // 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.4.13; */
                      
                      contract DSMath {
                          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);
                          }
                      
                          function min(uint x, uint y) internal pure returns (uint z) {
                              return x <= y ? x : y;
                          }
                          function max(uint x, uint y) internal pure returns (uint z) {
                              return x >= y ? x : y;
                          }
                          function imin(int x, int y) internal pure returns (int z) {
                              return x <= y ? x : y;
                          }
                          function imax(int x, int y) internal pure returns (int z) {
                              return x >= y ? x : y;
                          }
                      
                          uint constant WAD = 10 ** 18;
                          uint constant RAY = 10 ** 27;
                      
                          function wmul(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, y), WAD / 2) / WAD;
                          }
                          function rmul(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, y), RAY / 2) / RAY;
                          }
                          function wdiv(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, WAD), y / 2) / y;
                          }
                          function rdiv(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, RAY), y / 2) / y;
                          }
                      
                          // This famous algorithm is called "exponentiation by squaring"
                          // and calculates x^n with x as fixed-point and n as regular unsigned.
                          //
                          // It's O(log n), instead of O(n) for naive repeated multiplication.
                          //
                          // These facts are why it works:
                          //
                          //  If n is even, then x^n = (x^2)^(n/2).
                          //  If n is odd,  then x^n = x * x^(n-1),
                          //   and applying the equation for even x gives
                          //    x^n = x * (x^2)^((n-1) / 2).
                          //
                          //  Also, EVM division is flooring and
                          //    floor[(n-1) / 2] = floor[n / 2].
                          //
                          function rpow(uint x, uint n) internal pure returns (uint z) {
                              z = n % 2 != 0 ? x : RAY;
                      
                              for (n /= 2; n != 0; n /= 2) {
                                  x = rmul(x, x);
                      
                                  if (n % 2 != 0) {
                                      z = rmul(z, x);
                                  }
                              }
                          }
                      }
                      
                      ////// lib/ds-thing/src/thing.sol
                      // thing.sol - `auth` with handy mixins. your things should be DSThings
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import 'ds-auth/auth.sol'; */
                      /* import 'ds-note/note.sol'; */
                      /* import 'ds-math/math.sol'; */
                      
                      contract DSThing is DSAuth, DSNote, DSMath {
                      
                          function S(string s) internal pure returns (bytes4) {
                              return bytes4(keccak256(s));
                          }
                      
                      }
                      
                      ////// lib/ds-token/lib/ds-stop/src/stop.sol
                      /// stop.sol -- mixin for enable/disable functionality
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import "ds-auth/auth.sol"; */
                      /* import "ds-note/note.sol"; */
                      
                      contract DSStop is DSNote, DSAuth {
                      
                          bool public stopped;
                      
                          modifier stoppable {
                              require(!stopped);
                              _;
                          }
                          function stop() public auth note {
                              stopped = true;
                          }
                          function start() public auth note {
                              stopped = false;
                          }
                      
                      }
                      
                      ////// lib/ds-token/lib/erc20/src/erc20.sol
                      /// erc20.sol -- API for the ERC20 token standard
                      
                      // See <https://github.com/ethereum/EIPs/issues/20>.
                      
                      // This file likely does not meet the threshold of originality
                      // required for copyright to apply.  As a result, this is free and
                      // unencumbered software belonging to the public domain.
                      
                      /* pragma solidity ^0.4.8; */
                      
                      contract ERC20Events {
                          event Approval(address indexed src, address indexed guy, uint wad);
                          event Transfer(address indexed src, address indexed dst, uint wad);
                      }
                      
                      contract ERC20 is ERC20Events {
                          function totalSupply() public view returns (uint);
                          function balanceOf(address guy) public view returns (uint);
                          function allowance(address src, address guy) public view returns (uint);
                      
                          function approve(address guy, uint wad) public returns (bool);
                          function transfer(address dst, uint wad) public returns (bool);
                          function transferFrom(
                              address src, address dst, uint wad
                          ) public returns (bool);
                      }
                      
                      ////// lib/ds-token/src/base.sol
                      /// base.sol -- basic ERC20 implementation
                      
                      // Copyright (C) 2015, 2016, 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import "erc20/erc20.sol"; */
                      /* import "ds-math/math.sol"; */
                      
                      contract DSTokenBase is ERC20, DSMath {
                          uint256                                            _supply;
                          mapping (address => uint256)                       _balances;
                          mapping (address => mapping (address => uint256))  _approvals;
                      
                          function DSTokenBase(uint supply) public {
                              _balances[msg.sender] = supply;
                              _supply = supply;
                          }
                      
                          function totalSupply() public view returns (uint) {
                              return _supply;
                          }
                          function balanceOf(address src) public view returns (uint) {
                              return _balances[src];
                          }
                          function allowance(address src, address guy) public view returns (uint) {
                              return _approvals[src][guy];
                          }
                      
                          function transfer(address dst, uint wad) public returns (bool) {
                              return transferFrom(msg.sender, dst, wad);
                          }
                      
                          function transferFrom(address src, address dst, uint wad)
                              public
                              returns (bool)
                          {
                              if (src != msg.sender) {
                                  _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
                              }
                      
                              _balances[src] = sub(_balances[src], wad);
                              _balances[dst] = add(_balances[dst], wad);
                      
                              Transfer(src, dst, wad);
                      
                              return true;
                          }
                      
                          function approve(address guy, uint wad) public returns (bool) {
                              _approvals[msg.sender][guy] = wad;
                      
                              Approval(msg.sender, guy, wad);
                      
                              return true;
                          }
                      }
                      
                      ////// lib/ds-token/src/token.sol
                      /// token.sol -- ERC20 implementation with minting and burning
                      
                      // Copyright (C) 2015, 2016, 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import "ds-stop/stop.sol"; */
                      
                      /* import "./base.sol"; */
                      
                      contract DSToken is DSTokenBase(0), DSStop {
                      
                          bytes32  public  symbol;
                          uint256  public  decimals = 18; // standard token precision. override to customize
                      
                          function DSToken(bytes32 symbol_) public {
                              symbol = symbol_;
                          }
                      
                          event Mint(address indexed guy, uint wad);
                          event Burn(address indexed guy, uint wad);
                      
                          function approve(address guy) public stoppable returns (bool) {
                              return super.approve(guy, uint(-1));
                          }
                      
                          function approve(address guy, uint wad) public stoppable returns (bool) {
                              return super.approve(guy, wad);
                          }
                      
                          function transferFrom(address src, address dst, uint wad)
                              public
                              stoppable
                              returns (bool)
                          {
                              if (src != msg.sender && _approvals[src][msg.sender] != uint(-1)) {
                                  _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
                              }
                      
                              _balances[src] = sub(_balances[src], wad);
                              _balances[dst] = add(_balances[dst], wad);
                      
                              Transfer(src, dst, wad);
                      
                              return true;
                          }
                      
                          function push(address dst, uint wad) public {
                              transferFrom(msg.sender, dst, wad);
                          }
                          function pull(address src, uint wad) public {
                              transferFrom(src, msg.sender, wad);
                          }
                          function move(address src, address dst, uint wad) public {
                              transferFrom(src, dst, wad);
                          }
                      
                          function mint(uint wad) public {
                              mint(msg.sender, wad);
                          }
                          function burn(uint wad) public {
                              burn(msg.sender, wad);
                          }
                          function mint(address guy, uint wad) public auth stoppable {
                              _balances[guy] = add(_balances[guy], wad);
                              _supply = add(_supply, wad);
                              Mint(guy, wad);
                          }
                          function burn(address guy, uint wad) public auth stoppable {
                              if (guy != msg.sender && _approvals[guy][msg.sender] != uint(-1)) {
                                  _approvals[guy][msg.sender] = sub(_approvals[guy][msg.sender], wad);
                              }
                      
                              _balances[guy] = sub(_balances[guy], wad);
                              _supply = sub(_supply, wad);
                              Burn(guy, wad);
                          }
                      
                          // Optional token name
                          bytes32   public  name = "";
                      
                          function setName(bytes32 name_) public auth {
                              name = name_;
                          }
                      }
                      
                      ////// lib/ds-value/src/value.sol
                      /// value.sol - a value is a simple thing, it can be get and set
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import 'ds-thing/thing.sol'; */
                      
                      contract DSValue is DSThing {
                          bool    has;
                          bytes32 val;
                          function peek() public view returns (bytes32, bool) {
                              return (val,has);
                          }
                          function read() public view returns (bytes32) {
                              var (wut, haz) = peek();
                              assert(haz);
                              return wut;
                          }
                          function poke(bytes32 wut) public note auth {
                              val = wut;
                              has = true;
                          }
                          function void() public note auth {  // unset the value
                              has = false;
                          }
                      }
                      
                      ////// src/vox.sol
                      /// vox.sol -- target price feed
                      
                      // Copyright (C) 2016, 2017  Nikolai Mushegian <[email protected]>
                      // Copyright (C) 2016, 2017  Daniel Brockman <[email protected]>
                      // Copyright (C) 2017        Rain Break <[email protected]>
                      
                      // 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.4.18; */
                      
                      /* import "ds-thing/thing.sol"; */
                      
                      contract SaiVox is DSThing {
                          uint256  _par;
                          uint256  _way;
                      
                          uint256  public  fix;
                          uint256  public  how;
                          uint256  public  tau;
                      
                          function SaiVox(uint par_) public {
                              _par = fix = par_;
                              _way = RAY;
                              tau  = era();
                          }
                      
                          function era() public view returns (uint) {
                              return block.timestamp;
                          }
                      
                          function mold(bytes32 param, uint val) public note auth {
                              if (param == 'way') _way = val;
                          }
                      
                          // Dai Target Price (ref per dai)
                          function par() public returns (uint) {
                              prod();
                              return _par;
                          }
                          function way() public returns (uint) {
                              prod();
                              return _way;
                          }
                      
                          function tell(uint256 ray) public note auth {
                              fix = ray;
                          }
                          function tune(uint256 ray) public note auth {
                              how = ray;
                          }
                      
                          function prod() public note {
                              var age = era() - tau;
                              if (age == 0) return;  // optimised
                              tau = era();
                      
                              if (_way != RAY) _par = rmul(_par, rpow(_way, age));  // optimised
                      
                              if (how == 0) return;  // optimised
                              var wag = int128(how * age);
                              _way = inj(prj(_way) + (fix < _par ? wag : -wag));
                          }
                      
                          function inj(int128 x) internal pure returns (uint256) {
                              return x >= 0 ? uint256(x) + RAY
                                  : rdiv(RAY, RAY + uint256(-x));
                          }
                          function prj(uint256 x) internal pure returns (int128) {
                              return x >= RAY ? int128(x - RAY)
                                  : int128(RAY) - int128(rdiv(RAY, x));
                          }
                      }
                      
                      ////// src/tub.sol
                      /// tub.sol -- simplified CDP engine (baby brother of `vat')
                      
                      // Copyright (C) 2017  Nikolai Mushegian <[email protected]>
                      // Copyright (C) 2017  Daniel Brockman <[email protected]>
                      // Copyright (C) 2017  Rain Break <[email protected]>
                      
                      // 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.4.18; */
                      
                      /* import "ds-thing/thing.sol"; */
                      /* import "ds-token/token.sol"; */
                      /* import "ds-value/value.sol"; */
                      
                      /* import "./vox.sol"; */
                      
                      contract SaiTubEvents {
                          event LogNewCup(address indexed lad, bytes32 cup);
                      }
                      
                      contract SaiTub is DSThing, SaiTubEvents {
                          DSToken  public  sai;  // Stablecoin
                          DSToken  public  sin;  // Debt (negative sai)
                      
                          DSToken  public  skr;  // Abstracted collateral
                          ERC20    public  gem;  // Underlying collateral
                      
                          DSToken  public  gov;  // Governance token
                      
                          SaiVox   public  vox;  // Target price feed
                          DSValue  public  pip;  // Reference price feed
                          DSValue  public  pep;  // Governance price feed
                      
                          address  public  tap;  // Liquidator
                          address  public  pit;  // Governance Vault
                      
                          uint256  public  axe;  // Liquidation penalty
                          uint256  public  cap;  // Debt ceiling
                          uint256  public  mat;  // Liquidation ratio
                          uint256  public  tax;  // Stability fee
                          uint256  public  fee;  // Governance fee
                          uint256  public  gap;  // Join-Exit Spread
                      
                          bool     public  off;  // Cage flag
                          bool     public  out;  // Post cage exit
                      
                          uint256  public  fit;  // REF per SKR (just before settlement)
                      
                          uint256  public  rho;  // Time of last drip
                          uint256         _chi;  // Accumulated Tax Rates
                          uint256         _rhi;  // Accumulated Tax + Fee Rates
                          uint256  public  rum;  // Total normalised debt
                      
                          uint256                   public  cupi;
                          mapping (bytes32 => Cup)  public  cups;
                      
                          struct Cup {
                              address  lad;      // CDP owner
                              uint256  ink;      // Locked collateral (in SKR)
                              uint256  art;      // Outstanding normalised debt (tax only)
                              uint256  ire;      // Outstanding normalised debt
                          }
                      
                          function lad(bytes32 cup) public view returns (address) {
                              return cups[cup].lad;
                          }
                          function ink(bytes32 cup) public view returns (uint) {
                              return cups[cup].ink;
                          }
                          function tab(bytes32 cup) public returns (uint) {
                              return rmul(cups[cup].art, chi());
                          }
                          function rap(bytes32 cup) public returns (uint) {
                              return sub(rmul(cups[cup].ire, rhi()), tab(cup));
                          }
                      
                          // Total CDP Debt
                          function din() public returns (uint) {
                              return rmul(rum, chi());
                          }
                          // Backing collateral
                          function air() public view returns (uint) {
                              return skr.balanceOf(this);
                          }
                          // Raw collateral
                          function pie() public view returns (uint) {
                              return gem.balanceOf(this);
                          }
                      
                          //------------------------------------------------------------------
                      
                          function SaiTub(
                              DSToken  sai_,
                              DSToken  sin_,
                              DSToken  skr_,
                              ERC20    gem_,
                              DSToken  gov_,
                              DSValue  pip_,
                              DSValue  pep_,
                              SaiVox   vox_,
                              address  pit_
                          ) public {
                              gem = gem_;
                              skr = skr_;
                      
                              sai = sai_;
                              sin = sin_;
                      
                              gov = gov_;
                              pit = pit_;
                      
                              pip = pip_;
                              pep = pep_;
                              vox = vox_;
                      
                              axe = RAY;
                              mat = RAY;
                              tax = RAY;
                              fee = RAY;
                              gap = WAD;
                      
                              _chi = RAY;
                              _rhi = RAY;
                      
                              rho = era();
                          }
                      
                          function era() public constant returns (uint) {
                              return block.timestamp;
                          }
                      
                          //--Risk-parameter-config-------------------------------------------
                      
                          function mold(bytes32 param, uint val) public note auth {
                              if      (param == 'cap') cap = val;
                              else if (param == 'mat') { require(val >= RAY); mat = val; }
                              else if (param == 'tax') { require(val >= RAY); drip(); tax = val; }
                              else if (param == 'fee') { require(val >= RAY); drip(); fee = val; }
                              else if (param == 'axe') { require(val >= RAY); axe = val; }
                              else if (param == 'gap') { require(val >= WAD); gap = val; }
                              else return;
                          }
                      
                          //--Price-feed-setters----------------------------------------------
                      
                          function setPip(DSValue pip_) public note auth {
                              pip = pip_;
                          }
                          function setPep(DSValue pep_) public note auth {
                              pep = pep_;
                          }
                          function setVox(SaiVox vox_) public note auth {
                              vox = vox_;
                          }
                      
                          //--Tap-setter------------------------------------------------------
                          function turn(address tap_) public note {
                              require(tap  == 0);
                              require(tap_ != 0);
                              tap = tap_;
                          }
                      
                          //--Collateral-wrapper----------------------------------------------
                      
                          // Wrapper ratio (gem per skr)
                          function per() public view returns (uint ray) {
                              return skr.totalSupply() == 0 ? RAY : rdiv(pie(), skr.totalSupply());
                          }
                          // Join price (gem per skr)
                          function ask(uint wad) public view returns (uint) {
                              return rmul(wad, wmul(per(), gap));
                          }
                          // Exit price (gem per skr)
                          function bid(uint wad) public view returns (uint) {
                              return rmul(wad, wmul(per(), sub(2 * WAD, gap)));
                          }
                          function join(uint wad) public note {
                              require(!off);
                              require(ask(wad) > 0);
                              require(gem.transferFrom(msg.sender, this, ask(wad)));
                              skr.mint(msg.sender, wad);
                          }
                          function exit(uint wad) public note {
                              require(!off || out);
                              require(gem.transfer(msg.sender, bid(wad)));
                              skr.burn(msg.sender, wad);
                          }
                      
                          //--Stability-fee-accumulation--------------------------------------
                      
                          // Accumulated Rates
                          function chi() public returns (uint) {
                              drip();
                              return _chi;
                          }
                          function rhi() public returns (uint) {
                              drip();
                              return _rhi;
                          }
                          function drip() public note {
                              if (off) return;
                      
                              var rho_ = era();
                              var age = rho_ - rho;
                              if (age == 0) return;    // optimised
                              rho = rho_;
                      
                              var inc = RAY;
                      
                              if (tax != RAY) {  // optimised
                                  var _chi_ = _chi;
                                  inc = rpow(tax, age);
                                  _chi = rmul(_chi, inc);
                                  sai.mint(tap, rmul(sub(_chi, _chi_), rum));
                              }
                      
                              // optimised
                              if (fee != RAY) inc = rmul(inc, rpow(fee, age));
                              if (inc != RAY) _rhi = rmul(_rhi, inc);
                          }
                      
                      
                          //--CDP-risk-indicator----------------------------------------------
                      
                          // Abstracted collateral price (ref per skr)
                          function tag() public view returns (uint wad) {
                              return off ? fit : wmul(per(), uint(pip.read()));
                          }
                          // Returns true if cup is well-collateralized
                          function safe(bytes32 cup) public returns (bool) {
                              var pro = rmul(tag(), ink(cup));
                              var con = rmul(vox.par(), tab(cup));
                              var min = rmul(con, mat);
                              return pro >= min;
                          }
                      
                      
                          //--CDP-operations--------------------------------------------------
                      
                          function open() public note returns (bytes32 cup) {
                              require(!off);
                              cupi = add(cupi, 1);
                              cup = bytes32(cupi);
                              cups[cup].lad = msg.sender;
                              LogNewCup(msg.sender, cup);
                          }
                          function give(bytes32 cup, address guy) public note {
                              require(msg.sender == cups[cup].lad);
                              require(guy != 0);
                              cups[cup].lad = guy;
                          }
                      
                          function lock(bytes32 cup, uint wad) public note {
                              require(!off);
                              cups[cup].ink = add(cups[cup].ink, wad);
                              skr.pull(msg.sender, wad);
                              require(cups[cup].ink == 0 || cups[cup].ink > 0.005 ether);
                          }
                          function free(bytes32 cup, uint wad) public note {
                              require(msg.sender == cups[cup].lad);
                              cups[cup].ink = sub(cups[cup].ink, wad);
                              skr.push(msg.sender, wad);
                              require(safe(cup));
                              require(cups[cup].ink == 0 || cups[cup].ink > 0.005 ether);
                          }
                      
                          function draw(bytes32 cup, uint wad) public note {
                              require(!off);
                              require(msg.sender == cups[cup].lad);
                              require(rdiv(wad, chi()) > 0);
                      
                              cups[cup].art = add(cups[cup].art, rdiv(wad, chi()));
                              rum = add(rum, rdiv(wad, chi()));
                      
                              cups[cup].ire = add(cups[cup].ire, rdiv(wad, rhi()));
                              sai.mint(cups[cup].lad, wad);
                      
                              require(safe(cup));
                              require(sai.totalSupply() <= cap);
                          }
                          function wipe(bytes32 cup, uint wad) public note {
                              require(!off);
                      
                              var owe = rmul(wad, rdiv(rap(cup), tab(cup)));
                      
                              cups[cup].art = sub(cups[cup].art, rdiv(wad, chi()));
                              rum = sub(rum, rdiv(wad, chi()));
                      
                              cups[cup].ire = sub(cups[cup].ire, rdiv(add(wad, owe), rhi()));
                              sai.burn(msg.sender, wad);
                      
                              var (val, ok) = pep.peek();
                              if (ok && val != 0) gov.move(msg.sender, pit, wdiv(owe, uint(val)));
                          }
                      
                          function shut(bytes32 cup) public note {
                              require(!off);
                              require(msg.sender == cups[cup].lad);
                              if (tab(cup) != 0) wipe(cup, tab(cup));
                              if (ink(cup) != 0) free(cup, ink(cup));
                              delete cups[cup];
                          }
                      
                          function bite(bytes32 cup) public note {
                              require(!safe(cup) || off);
                      
                              // Take on all of the debt, except unpaid fees
                              var rue = tab(cup);
                              sin.mint(tap, rue);
                              rum = sub(rum, cups[cup].art);
                              cups[cup].art = 0;
                              cups[cup].ire = 0;
                      
                              // Amount owed in SKR, including liquidation penalty
                              var owe = rdiv(rmul(rmul(rue, axe), vox.par()), tag());
                      
                              if (owe > cups[cup].ink) {
                                  owe = cups[cup].ink;
                              }
                      
                              skr.push(tap, owe);
                              cups[cup].ink = sub(cups[cup].ink, owe);
                          }
                      
                          //------------------------------------------------------------------
                      
                          function cage(uint fit_, uint jam) public note auth {
                              require(!off && fit_ != 0);
                              off = true;
                              axe = RAY;
                              gap = WAD;
                              fit = fit_;         // ref per skr
                              require(gem.transfer(tap, jam));
                          }
                          function flow() public note auth {
                              require(off);
                              out = true;
                          }
                      }
                      
                      ////// src/tap.sol
                      /// tap.sol -- liquidation engine (see also `vow`)
                      
                      // Copyright (C) 2017  Nikolai Mushegian <[email protected]>
                      // Copyright (C) 2017  Daniel Brockman <[email protected]>
                      // Copyright (C) 2017  Rain Break <[email protected]>
                      
                      // 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.4.18; */
                      
                      /* import "./tub.sol"; */
                      
                      contract SaiTap is DSThing {
                          DSToken  public  sai;
                          DSToken  public  sin;
                          DSToken  public  skr;
                      
                          SaiVox   public  vox;
                          SaiTub   public  tub;
                      
                          uint256  public  gap;  // Boom-Bust Spread
                          bool     public  off;  // Cage flag
                          uint256  public  fix;  // Cage price
                      
                          // Surplus
                          function joy() public view returns (uint) {
                              return sai.balanceOf(this);
                          }
                          // Bad debt
                          function woe() public view returns (uint) {
                              return sin.balanceOf(this);
                          }
                          // Collateral pending liquidation
                          function fog() public view returns (uint) {
                              return skr.balanceOf(this);
                          }
                      
                      
                          function SaiTap(SaiTub tub_) public {
                              tub = tub_;
                      
                              sai = tub.sai();
                              sin = tub.sin();
                              skr = tub.skr();
                      
                              vox = tub.vox();
                      
                              gap = WAD;
                          }
                      
                          function mold(bytes32 param, uint val) public note auth {
                              if (param == 'gap') gap = val;
                          }
                      
                          // Cancel debt
                          function heal() public note {
                              if (joy() == 0 || woe() == 0) return;  // optimised
                              var wad = min(joy(), woe());
                              sai.burn(wad);
                              sin.burn(wad);
                          }
                      
                          // Feed price (sai per skr)
                          function s2s() public returns (uint) {
                              var tag = tub.tag();    // ref per skr
                              var par = vox.par();    // ref per sai
                              return rdiv(tag, par);  // sai per skr
                          }
                          // Boom price (sai per skr)
                          function bid(uint wad) public returns (uint) {
                              return rmul(wad, wmul(s2s(), sub(2 * WAD, gap)));
                          }
                          // Bust price (sai per skr)
                          function ask(uint wad) public returns (uint) {
                              return rmul(wad, wmul(s2s(), gap));
                          }
                          function flip(uint wad) internal {
                              require(ask(wad) > 0);
                              skr.push(msg.sender, wad);
                              sai.pull(msg.sender, ask(wad));
                              heal();
                          }
                          function flop(uint wad) internal {
                              skr.mint(sub(wad, fog()));
                              flip(wad);
                              require(joy() == 0);  // can't flop into surplus
                          }
                          function flap(uint wad) internal {
                              heal();
                              sai.push(msg.sender, bid(wad));
                              skr.burn(msg.sender, wad);
                          }
                          function bust(uint wad) public note {
                              require(!off);
                              if (wad > fog()) flop(wad);
                              else flip(wad);
                          }
                          function boom(uint wad) public note {
                              require(!off);
                              flap(wad);
                          }
                      
                          //------------------------------------------------------------------
                      
                          function cage(uint fix_) public note auth {
                              require(!off);
                              off = true;
                              fix = fix_;
                          }
                          function cash(uint wad) public note {
                              require(off);
                              sai.burn(msg.sender, wad);
                              require(tub.gem().transfer(msg.sender, rmul(wad, fix)));
                          }
                          function mock(uint wad) public note {
                              require(off);
                              sai.mint(msg.sender, wad);
                              require(tub.gem().transferFrom(msg.sender, this, rmul(wad, fix)));
                          }
                          function vent() public note {
                              require(off);
                              skr.burn(fog());
                          }
                      }
                      
                      ////// src/top.sol
                      /// top.sol -- global settlement manager
                      
                      // Copyright (C) 2017  Nikolai Mushegian <[email protected]>
                      // Copyright (C) 2017  Daniel Brockman <[email protected]>
                      // Copyright (C) 2017  Rain Break <[email protected]>
                      
                      // 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.4.18; */
                      
                      /* import "./tub.sol"; */
                      /* import "./tap.sol"; */
                      
                      contract SaiTop is DSThing {
                          SaiVox   public  vox;
                          SaiTub   public  tub;
                          SaiTap   public  tap;
                      
                          DSToken  public  sai;
                          DSToken  public  sin;
                          DSToken  public  skr;
                          ERC20    public  gem;
                      
                          uint256  public  fix;  // sai cage price (gem per sai)
                          uint256  public  fit;  // skr cage price (ref per skr)
                          uint256  public  caged;
                          uint256  public  cooldown = 6 hours;
                      
                          function SaiTop(SaiTub tub_, SaiTap tap_) public {
                              tub = tub_;
                              tap = tap_;
                      
                              vox = tub.vox();
                      
                              sai = tub.sai();
                              sin = tub.sin();
                              skr = tub.skr();
                              gem = tub.gem();
                          }
                      
                          function era() public view returns (uint) {
                              return block.timestamp;
                          }
                      
                          // force settlement of the system at a given price (sai per gem).
                          // This is nearly the equivalent of biting all cups at once.
                          // Important consideration: the gems associated with free skr can
                          // be tapped to make sai whole.
                          function cage(uint price) internal {
                              require(!tub.off() && price != 0);
                              caged = era();
                      
                              tub.drip();  // collect remaining fees
                              tap.heal();  // absorb any pending fees
                      
                              fit = rmul(wmul(price, vox.par()), tub.per());
                              // Most gems we can get per sai is the full balance of the tub.
                              // If there is no sai issued, we should still be able to cage.
                              if (sai.totalSupply() == 0) {
                                  fix = rdiv(WAD, price);
                              } else {
                                  fix = min(rdiv(WAD, price), rdiv(tub.pie(), sai.totalSupply()));
                              }
                      
                              tub.cage(fit, rmul(fix, sai.totalSupply()));
                              tap.cage(fix);
                      
                              tap.vent();    // burn pending sale skr
                          }
                          // cage by reading the last value from the feed for the price
                          function cage() public note auth {
                              cage(rdiv(uint(tub.pip().read()), vox.par()));
                          }
                      
                          function flow() public note {
                              require(tub.off());
                              var empty = tub.din() == 0 && tap.fog() == 0;
                              var ended = era() > caged + cooldown;
                              require(empty || ended);
                              tub.flow();
                          }
                      
                          function setCooldown(uint cooldown_) public auth {
                              cooldown = cooldown_;
                          }
                      }
                      
                      ////// src/mom.sol
                      /// mom.sol -- admin manager
                      
                      // Copyright (C) 2017  Nikolai Mushegian <[email protected]>
                      // Copyright (C) 2017  Daniel Brockman <[email protected]>
                      // Copyright (C) 2017  Rain <[email protected]>
                      
                      // 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.4.18; */
                      
                      /* import 'ds-thing/thing.sol'; */
                      /* import './tub.sol'; */
                      /* import './top.sol'; */
                      /* import './tap.sol'; */
                      
                      contract SaiMom is DSThing {
                          SaiTub  public  tub;
                          SaiTap  public  tap;
                          SaiVox  public  vox;
                      
                          function SaiMom(SaiTub tub_, SaiTap tap_, SaiVox vox_) public {
                              tub = tub_;
                              tap = tap_;
                              vox = vox_;
                          }
                          // Debt ceiling
                          function setCap(uint wad) public note auth {
                              tub.mold("cap", wad);
                          }
                          // Liquidation ratio
                          function setMat(uint ray) public note auth {
                              tub.mold("mat", ray);
                              var axe = tub.axe();
                              var mat = tub.mat();
                              require(axe >= RAY && axe <= mat);
                          }
                          // Stability fee
                          function setTax(uint ray) public note auth {
                              tub.mold("tax", ray);
                              var tax = tub.tax();
                              require(RAY <= tax);
                              require(tax < 1000001100000000000000000000);  // 10% / day
                          }
                          // Governance fee
                          function setFee(uint ray) public note auth {
                              tub.mold("fee", ray);
                              var fee = tub.fee();
                              require(RAY <= fee);
                              require(fee < 1000001100000000000000000000);  // 10% / day
                          }
                          // Liquidation fee
                          function setAxe(uint ray) public note auth {
                              tub.mold("axe", ray);
                              var axe = tub.axe();
                              var mat = tub.mat();
                              require(axe >= RAY && axe <= mat);
                          }
                          // Join/Exit Spread
                          function setTubGap(uint wad) public note auth {
                              tub.mold("gap", wad);
                          }
                          // ETH/USD Feed
                          function setPip(DSValue pip_) public note auth {
                              tub.setPip(pip_);
                          }
                          // MKR/USD Feed
                          function setPep(DSValue pep_) public note auth {
                              tub.setPep(pep_);
                          }
                          // TRFM
                          function setVox(SaiVox vox_) public note auth {
                              tub.setVox(vox_);
                          }
                          // Boom/Bust Spread
                          function setTapGap(uint wad) public note auth {
                              tap.mold("gap", wad);
                              var gap = tap.gap();
                              require(gap <= 1.05 ether);
                              require(gap >= 0.95 ether);
                          }
                          // Rate of change of target price (per second)
                          function setWay(uint ray) public note auth {
                              require(ray < 1000001100000000000000000000);  // 10% / day
                              require(ray >  999998800000000000000000000);
                              vox.mold("way", ray);
                          }
                          function setHow(uint ray) public note auth {
                              vox.tune(ray);
                          }
                      }

                      File 6 of 9: SaiTub
                      // hevm: flattened sources of src/tub.sol
                      pragma solidity ^0.4.18;
                      
                      ////// lib/ds-guard/lib/ds-auth/src/auth.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.4.13; */
                      
                      contract DSAuthority {
                          function canCall(
                              address src, address dst, bytes4 sig
                          ) public view returns (bool);
                      }
                      
                      contract DSAuthEvents {
                          event LogSetAuthority (address indexed authority);
                          event LogSetOwner     (address indexed owner);
                      }
                      
                      contract DSAuth is DSAuthEvents {
                          DSAuthority  public  authority;
                          address      public  owner;
                      
                          function DSAuth() public {
                              owner = msg.sender;
                              LogSetOwner(msg.sender);
                          }
                      
                          function setOwner(address owner_)
                              public
                              auth
                          {
                              owner = owner_;
                              LogSetOwner(owner);
                          }
                      
                          function setAuthority(DSAuthority authority_)
                              public
                              auth
                          {
                              authority = authority_;
                              LogSetAuthority(authority);
                          }
                      
                          modifier auth {
                              require(isAuthorized(msg.sender, msg.sig));
                              _;
                          }
                      
                          function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
                              if (src == address(this)) {
                                  return true;
                              } else if (src == owner) {
                                  return true;
                              } else if (authority == DSAuthority(0)) {
                                  return false;
                              } else {
                                  return authority.canCall(src, this, sig);
                              }
                          }
                      }
                      
                      ////// lib/ds-spell/lib/ds-note/src/note.sol
                      /// note.sol -- the `note' modifier, for logging calls as events
                      
                      // 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.4.13; */
                      
                      contract DSNote {
                          event LogNote(
                              bytes4   indexed  sig,
                              address  indexed  guy,
                              bytes32  indexed  foo,
                              bytes32  indexed  bar,
                              uint              wad,
                              bytes             fax
                          ) anonymous;
                      
                          modifier note {
                              bytes32 foo;
                              bytes32 bar;
                      
                              assembly {
                                  foo := calldataload(4)
                                  bar := calldataload(36)
                              }
                      
                              LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);
                      
                              _;
                          }
                      }
                      
                      ////// lib/ds-thing/lib/ds-math/src/math.sol
                      /// math.sol -- mixin for inline numerical wizardry
                      
                      // 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.4.13; */
                      
                      contract DSMath {
                          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);
                          }
                      
                          function min(uint x, uint y) internal pure returns (uint z) {
                              return x <= y ? x : y;
                          }
                          function max(uint x, uint y) internal pure returns (uint z) {
                              return x >= y ? x : y;
                          }
                          function imin(int x, int y) internal pure returns (int z) {
                              return x <= y ? x : y;
                          }
                          function imax(int x, int y) internal pure returns (int z) {
                              return x >= y ? x : y;
                          }
                      
                          uint constant WAD = 10 ** 18;
                          uint constant RAY = 10 ** 27;
                      
                          function wmul(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, y), WAD / 2) / WAD;
                          }
                          function rmul(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, y), RAY / 2) / RAY;
                          }
                          function wdiv(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, WAD), y / 2) / y;
                          }
                          function rdiv(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, RAY), y / 2) / y;
                          }
                      
                          // This famous algorithm is called "exponentiation by squaring"
                          // and calculates x^n with x as fixed-point and n as regular unsigned.
                          //
                          // It's O(log n), instead of O(n) for naive repeated multiplication.
                          //
                          // These facts are why it works:
                          //
                          //  If n is even, then x^n = (x^2)^(n/2).
                          //  If n is odd,  then x^n = x * x^(n-1),
                          //   and applying the equation for even x gives
                          //    x^n = x * (x^2)^((n-1) / 2).
                          //
                          //  Also, EVM division is flooring and
                          //    floor[(n-1) / 2] = floor[n / 2].
                          //
                          function rpow(uint x, uint n) internal pure returns (uint z) {
                              z = n % 2 != 0 ? x : RAY;
                      
                              for (n /= 2; n != 0; n /= 2) {
                                  x = rmul(x, x);
                      
                                  if (n % 2 != 0) {
                                      z = rmul(z, x);
                                  }
                              }
                          }
                      }
                      
                      ////// lib/ds-thing/src/thing.sol
                      // thing.sol - `auth` with handy mixins. your things should be DSThings
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import 'ds-auth/auth.sol'; */
                      /* import 'ds-note/note.sol'; */
                      /* import 'ds-math/math.sol'; */
                      
                      contract DSThing is DSAuth, DSNote, DSMath {
                      
                          function S(string s) internal pure returns (bytes4) {
                              return bytes4(keccak256(s));
                          }
                      
                      }
                      
                      ////// lib/ds-token/lib/ds-stop/src/stop.sol
                      /// stop.sol -- mixin for enable/disable functionality
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import "ds-auth/auth.sol"; */
                      /* import "ds-note/note.sol"; */
                      
                      contract DSStop is DSNote, DSAuth {
                      
                          bool public stopped;
                      
                          modifier stoppable {
                              require(!stopped);
                              _;
                          }
                          function stop() public auth note {
                              stopped = true;
                          }
                          function start() public auth note {
                              stopped = false;
                          }
                      
                      }
                      
                      ////// lib/ds-token/lib/erc20/src/erc20.sol
                      /// erc20.sol -- API for the ERC20 token standard
                      
                      // See <https://github.com/ethereum/EIPs/issues/20>.
                      
                      // This file likely does not meet the threshold of originality
                      // required for copyright to apply.  As a result, this is free and
                      // unencumbered software belonging to the public domain.
                      
                      /* pragma solidity ^0.4.8; */
                      
                      contract ERC20Events {
                          event Approval(address indexed src, address indexed guy, uint wad);
                          event Transfer(address indexed src, address indexed dst, uint wad);
                      }
                      
                      contract ERC20 is ERC20Events {
                          function totalSupply() public view returns (uint);
                          function balanceOf(address guy) public view returns (uint);
                          function allowance(address src, address guy) public view returns (uint);
                      
                          function approve(address guy, uint wad) public returns (bool);
                          function transfer(address dst, uint wad) public returns (bool);
                          function transferFrom(
                              address src, address dst, uint wad
                          ) public returns (bool);
                      }
                      
                      ////// lib/ds-token/src/base.sol
                      /// base.sol -- basic ERC20 implementation
                      
                      // Copyright (C) 2015, 2016, 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import "erc20/erc20.sol"; */
                      /* import "ds-math/math.sol"; */
                      
                      contract DSTokenBase is ERC20, DSMath {
                          uint256                                            _supply;
                          mapping (address => uint256)                       _balances;
                          mapping (address => mapping (address => uint256))  _approvals;
                      
                          function DSTokenBase(uint supply) public {
                              _balances[msg.sender] = supply;
                              _supply = supply;
                          }
                      
                          function totalSupply() public view returns (uint) {
                              return _supply;
                          }
                          function balanceOf(address src) public view returns (uint) {
                              return _balances[src];
                          }
                          function allowance(address src, address guy) public view returns (uint) {
                              return _approvals[src][guy];
                          }
                      
                          function transfer(address dst, uint wad) public returns (bool) {
                              return transferFrom(msg.sender, dst, wad);
                          }
                      
                          function transferFrom(address src, address dst, uint wad)
                              public
                              returns (bool)
                          {
                              if (src != msg.sender) {
                                  _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
                              }
                      
                              _balances[src] = sub(_balances[src], wad);
                              _balances[dst] = add(_balances[dst], wad);
                      
                              Transfer(src, dst, wad);
                      
                              return true;
                          }
                      
                          function approve(address guy, uint wad) public returns (bool) {
                              _approvals[msg.sender][guy] = wad;
                      
                              Approval(msg.sender, guy, wad);
                      
                              return true;
                          }
                      }
                      
                      ////// lib/ds-token/src/token.sol
                      /// token.sol -- ERC20 implementation with minting and burning
                      
                      // Copyright (C) 2015, 2016, 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import "ds-stop/stop.sol"; */
                      
                      /* import "./base.sol"; */
                      
                      contract DSToken is DSTokenBase(0), DSStop {
                      
                          bytes32  public  symbol;
                          uint256  public  decimals = 18; // standard token precision. override to customize
                      
                          function DSToken(bytes32 symbol_) public {
                              symbol = symbol_;
                          }
                      
                          event Mint(address indexed guy, uint wad);
                          event Burn(address indexed guy, uint wad);
                      
                          function approve(address guy) public stoppable returns (bool) {
                              return super.approve(guy, uint(-1));
                          }
                      
                          function approve(address guy, uint wad) public stoppable returns (bool) {
                              return super.approve(guy, wad);
                          }
                      
                          function transferFrom(address src, address dst, uint wad)
                              public
                              stoppable
                              returns (bool)
                          {
                              if (src != msg.sender && _approvals[src][msg.sender] != uint(-1)) {
                                  _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
                              }
                      
                              _balances[src] = sub(_balances[src], wad);
                              _balances[dst] = add(_balances[dst], wad);
                      
                              Transfer(src, dst, wad);
                      
                              return true;
                          }
                      
                          function push(address dst, uint wad) public {
                              transferFrom(msg.sender, dst, wad);
                          }
                          function pull(address src, uint wad) public {
                              transferFrom(src, msg.sender, wad);
                          }
                          function move(address src, address dst, uint wad) public {
                              transferFrom(src, dst, wad);
                          }
                      
                          function mint(uint wad) public {
                              mint(msg.sender, wad);
                          }
                          function burn(uint wad) public {
                              burn(msg.sender, wad);
                          }
                          function mint(address guy, uint wad) public auth stoppable {
                              _balances[guy] = add(_balances[guy], wad);
                              _supply = add(_supply, wad);
                              Mint(guy, wad);
                          }
                          function burn(address guy, uint wad) public auth stoppable {
                              if (guy != msg.sender && _approvals[guy][msg.sender] != uint(-1)) {
                                  _approvals[guy][msg.sender] = sub(_approvals[guy][msg.sender], wad);
                              }
                      
                              _balances[guy] = sub(_balances[guy], wad);
                              _supply = sub(_supply, wad);
                              Burn(guy, wad);
                          }
                      
                          // Optional token name
                          bytes32   public  name = "";
                      
                          function setName(bytes32 name_) public auth {
                              name = name_;
                          }
                      }
                      
                      ////// lib/ds-value/src/value.sol
                      /// value.sol - a value is a simple thing, it can be get and set
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import 'ds-thing/thing.sol'; */
                      
                      contract DSValue is DSThing {
                          bool    has;
                          bytes32 val;
                          function peek() public view returns (bytes32, bool) {
                              return (val,has);
                          }
                          function read() public view returns (bytes32) {
                              var (wut, haz) = peek();
                              assert(haz);
                              return wut;
                          }
                          function poke(bytes32 wut) public note auth {
                              val = wut;
                              has = true;
                          }
                          function void() public note auth {  // unset the value
                              has = false;
                          }
                      }
                      
                      ////// src/vox.sol
                      /// vox.sol -- target price feed
                      
                      // Copyright (C) 2016, 2017  Nikolai Mushegian <[email protected]>
                      // Copyright (C) 2016, 2017  Daniel Brockman <[email protected]>
                      // Copyright (C) 2017        Rain Break <[email protected]>
                      
                      // 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.4.18; */
                      
                      /* import "ds-thing/thing.sol"; */
                      
                      contract SaiVox is DSThing {
                          uint256  _par;
                          uint256  _way;
                      
                          uint256  public  fix;
                          uint256  public  how;
                          uint256  public  tau;
                      
                          function SaiVox(uint par_) public {
                              _par = fix = par_;
                              _way = RAY;
                              tau  = era();
                          }
                      
                          function era() public view returns (uint) {
                              return block.timestamp;
                          }
                      
                          function mold(bytes32 param, uint val) public note auth {
                              if (param == 'way') _way = val;
                          }
                      
                          // Dai Target Price (ref per dai)
                          function par() public returns (uint) {
                              prod();
                              return _par;
                          }
                          function way() public returns (uint) {
                              prod();
                              return _way;
                          }
                      
                          function tell(uint256 ray) public note auth {
                              fix = ray;
                          }
                          function tune(uint256 ray) public note auth {
                              how = ray;
                          }
                      
                          function prod() public note {
                              var age = era() - tau;
                              if (age == 0) return;  // optimised
                              tau = era();
                      
                              if (_way != RAY) _par = rmul(_par, rpow(_way, age));  // optimised
                      
                              if (how == 0) return;  // optimised
                              var wag = int128(how * age);
                              _way = inj(prj(_way) + (fix < _par ? wag : -wag));
                          }
                      
                          function inj(int128 x) internal pure returns (uint256) {
                              return x >= 0 ? uint256(x) + RAY
                                  : rdiv(RAY, RAY + uint256(-x));
                          }
                          function prj(uint256 x) internal pure returns (int128) {
                              return x >= RAY ? int128(x - RAY)
                                  : int128(RAY) - int128(rdiv(RAY, x));
                          }
                      }
                      
                      ////// src/tub.sol
                      /// tub.sol -- simplified CDP engine (baby brother of `vat')
                      
                      // Copyright (C) 2017  Nikolai Mushegian <[email protected]>
                      // Copyright (C) 2017  Daniel Brockman <[email protected]>
                      // Copyright (C) 2017  Rain Break <[email protected]>
                      
                      // 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.4.18; */
                      
                      /* import "ds-thing/thing.sol"; */
                      /* import "ds-token/token.sol"; */
                      /* import "ds-value/value.sol"; */
                      
                      /* import "./vox.sol"; */
                      
                      contract SaiTubEvents {
                          event LogNewCup(address indexed lad, bytes32 cup);
                      }
                      
                      contract SaiTub is DSThing, SaiTubEvents {
                          DSToken  public  sai;  // Stablecoin
                          DSToken  public  sin;  // Debt (negative sai)
                      
                          DSToken  public  skr;  // Abstracted collateral
                          ERC20    public  gem;  // Underlying collateral
                      
                          DSToken  public  gov;  // Governance token
                      
                          SaiVox   public  vox;  // Target price feed
                          DSValue  public  pip;  // Reference price feed
                          DSValue  public  pep;  // Governance price feed
                      
                          address  public  tap;  // Liquidator
                          address  public  pit;  // Governance Vault
                      
                          uint256  public  axe;  // Liquidation penalty
                          uint256  public  cap;  // Debt ceiling
                          uint256  public  mat;  // Liquidation ratio
                          uint256  public  tax;  // Stability fee
                          uint256  public  fee;  // Governance fee
                          uint256  public  gap;  // Join-Exit Spread
                      
                          bool     public  off;  // Cage flag
                          bool     public  out;  // Post cage exit
                      
                          uint256  public  fit;  // REF per SKR (just before settlement)
                      
                          uint256  public  rho;  // Time of last drip
                          uint256         _chi;  // Accumulated Tax Rates
                          uint256         _rhi;  // Accumulated Tax + Fee Rates
                          uint256  public  rum;  // Total normalised debt
                      
                          uint256                   public  cupi;
                          mapping (bytes32 => Cup)  public  cups;
                      
                          struct Cup {
                              address  lad;      // CDP owner
                              uint256  ink;      // Locked collateral (in SKR)
                              uint256  art;      // Outstanding normalised debt (tax only)
                              uint256  ire;      // Outstanding normalised debt
                          }
                      
                          function lad(bytes32 cup) public view returns (address) {
                              return cups[cup].lad;
                          }
                          function ink(bytes32 cup) public view returns (uint) {
                              return cups[cup].ink;
                          }
                          function tab(bytes32 cup) public returns (uint) {
                              return rmul(cups[cup].art, chi());
                          }
                          function rap(bytes32 cup) public returns (uint) {
                              return sub(rmul(cups[cup].ire, rhi()), tab(cup));
                          }
                      
                          // Total CDP Debt
                          function din() public returns (uint) {
                              return rmul(rum, chi());
                          }
                          // Backing collateral
                          function air() public view returns (uint) {
                              return skr.balanceOf(this);
                          }
                          // Raw collateral
                          function pie() public view returns (uint) {
                              return gem.balanceOf(this);
                          }
                      
                          //------------------------------------------------------------------
                      
                          function SaiTub(
                              DSToken  sai_,
                              DSToken  sin_,
                              DSToken  skr_,
                              ERC20    gem_,
                              DSToken  gov_,
                              DSValue  pip_,
                              DSValue  pep_,
                              SaiVox   vox_,
                              address  pit_
                          ) public {
                              gem = gem_;
                              skr = skr_;
                      
                              sai = sai_;
                              sin = sin_;
                      
                              gov = gov_;
                              pit = pit_;
                      
                              pip = pip_;
                              pep = pep_;
                              vox = vox_;
                      
                              axe = RAY;
                              mat = RAY;
                              tax = RAY;
                              fee = RAY;
                              gap = WAD;
                      
                              _chi = RAY;
                              _rhi = RAY;
                      
                              rho = era();
                          }
                      
                          function era() public constant returns (uint) {
                              return block.timestamp;
                          }
                      
                          //--Risk-parameter-config-------------------------------------------
                      
                          function mold(bytes32 param, uint val) public note auth {
                              if      (param == 'cap') cap = val;
                              else if (param == 'mat') { require(val >= RAY); mat = val; }
                              else if (param == 'tax') { require(val >= RAY); drip(); tax = val; }
                              else if (param == 'fee') { require(val >= RAY); drip(); fee = val; }
                              else if (param == 'axe') { require(val >= RAY); axe = val; }
                              else if (param == 'gap') { require(val >= WAD); gap = val; }
                              else return;
                          }
                      
                          //--Price-feed-setters----------------------------------------------
                      
                          function setPip(DSValue pip_) public note auth {
                              pip = pip_;
                          }
                          function setPep(DSValue pep_) public note auth {
                              pep = pep_;
                          }
                          function setVox(SaiVox vox_) public note auth {
                              vox = vox_;
                          }
                      
                          //--Tap-setter------------------------------------------------------
                          function turn(address tap_) public note {
                              require(tap  == 0);
                              require(tap_ != 0);
                              tap = tap_;
                          }
                      
                          //--Collateral-wrapper----------------------------------------------
                      
                          // Wrapper ratio (gem per skr)
                          function per() public view returns (uint ray) {
                              return skr.totalSupply() == 0 ? RAY : rdiv(pie(), skr.totalSupply());
                          }
                          // Join price (gem per skr)
                          function ask(uint wad) public view returns (uint) {
                              return rmul(wad, wmul(per(), gap));
                          }
                          // Exit price (gem per skr)
                          function bid(uint wad) public view returns (uint) {
                              return rmul(wad, wmul(per(), sub(2 * WAD, gap)));
                          }
                          function join(uint wad) public note {
                              require(!off);
                              require(ask(wad) > 0);
                              require(gem.transferFrom(msg.sender, this, ask(wad)));
                              skr.mint(msg.sender, wad);
                          }
                          function exit(uint wad) public note {
                              require(!off || out);
                              require(gem.transfer(msg.sender, bid(wad)));
                              skr.burn(msg.sender, wad);
                          }
                      
                          //--Stability-fee-accumulation--------------------------------------
                      
                          // Accumulated Rates
                          function chi() public returns (uint) {
                              drip();
                              return _chi;
                          }
                          function rhi() public returns (uint) {
                              drip();
                              return _rhi;
                          }
                          function drip() public note {
                              if (off) return;
                      
                              var rho_ = era();
                              var age = rho_ - rho;
                              if (age == 0) return;    // optimised
                              rho = rho_;
                      
                              var inc = RAY;
                      
                              if (tax != RAY) {  // optimised
                                  var _chi_ = _chi;
                                  inc = rpow(tax, age);
                                  _chi = rmul(_chi, inc);
                                  sai.mint(tap, rmul(sub(_chi, _chi_), rum));
                              }
                      
                              // optimised
                              if (fee != RAY) inc = rmul(inc, rpow(fee, age));
                              if (inc != RAY) _rhi = rmul(_rhi, inc);
                          }
                      
                      
                          //--CDP-risk-indicator----------------------------------------------
                      
                          // Abstracted collateral price (ref per skr)
                          function tag() public view returns (uint wad) {
                              return off ? fit : wmul(per(), uint(pip.read()));
                          }
                          // Returns true if cup is well-collateralized
                          function safe(bytes32 cup) public returns (bool) {
                              var pro = rmul(tag(), ink(cup));
                              var con = rmul(vox.par(), tab(cup));
                              var min = rmul(con, mat);
                              return pro >= min;
                          }
                      
                      
                          //--CDP-operations--------------------------------------------------
                      
                          function open() public note returns (bytes32 cup) {
                              require(!off);
                              cupi = add(cupi, 1);
                              cup = bytes32(cupi);
                              cups[cup].lad = msg.sender;
                              LogNewCup(msg.sender, cup);
                          }
                          function give(bytes32 cup, address guy) public note {
                              require(msg.sender == cups[cup].lad);
                              require(guy != 0);
                              cups[cup].lad = guy;
                          }
                      
                          function lock(bytes32 cup, uint wad) public note {
                              require(!off);
                              cups[cup].ink = add(cups[cup].ink, wad);
                              skr.pull(msg.sender, wad);
                              require(cups[cup].ink == 0 || cups[cup].ink > 0.005 ether);
                          }
                          function free(bytes32 cup, uint wad) public note {
                              require(msg.sender == cups[cup].lad);
                              cups[cup].ink = sub(cups[cup].ink, wad);
                              skr.push(msg.sender, wad);
                              require(safe(cup));
                              require(cups[cup].ink == 0 || cups[cup].ink > 0.005 ether);
                          }
                      
                          function draw(bytes32 cup, uint wad) public note {
                              require(!off);
                              require(msg.sender == cups[cup].lad);
                              require(rdiv(wad, chi()) > 0);
                      
                              cups[cup].art = add(cups[cup].art, rdiv(wad, chi()));
                              rum = add(rum, rdiv(wad, chi()));
                      
                              cups[cup].ire = add(cups[cup].ire, rdiv(wad, rhi()));
                              sai.mint(cups[cup].lad, wad);
                      
                              require(safe(cup));
                              require(sai.totalSupply() <= cap);
                          }
                          function wipe(bytes32 cup, uint wad) public note {
                              require(!off);
                      
                              var owe = rmul(wad, rdiv(rap(cup), tab(cup)));
                      
                              cups[cup].art = sub(cups[cup].art, rdiv(wad, chi()));
                              rum = sub(rum, rdiv(wad, chi()));
                      
                              cups[cup].ire = sub(cups[cup].ire, rdiv(add(wad, owe), rhi()));
                              sai.burn(msg.sender, wad);
                      
                              var (val, ok) = pep.peek();
                              if (ok && val != 0) gov.move(msg.sender, pit, wdiv(owe, uint(val)));
                          }
                      
                          function shut(bytes32 cup) public note {
                              require(!off);
                              require(msg.sender == cups[cup].lad);
                              if (tab(cup) != 0) wipe(cup, tab(cup));
                              if (ink(cup) != 0) free(cup, ink(cup));
                              delete cups[cup];
                          }
                      
                          function bite(bytes32 cup) public note {
                              require(!safe(cup) || off);
                      
                              // Take on all of the debt, except unpaid fees
                              var rue = tab(cup);
                              sin.mint(tap, rue);
                              rum = sub(rum, cups[cup].art);
                              cups[cup].art = 0;
                              cups[cup].ire = 0;
                      
                              // Amount owed in SKR, including liquidation penalty
                              var owe = rdiv(rmul(rmul(rue, axe), vox.par()), tag());
                      
                              if (owe > cups[cup].ink) {
                                  owe = cups[cup].ink;
                              }
                      
                              skr.push(tap, owe);
                              cups[cup].ink = sub(cups[cup].ink, owe);
                          }
                      
                          //------------------------------------------------------------------
                      
                          function cage(uint fit_, uint jam) public note auth {
                              require(!off && fit_ != 0);
                              off = true;
                              axe = RAY;
                              gap = WAD;
                              fit = fit_;         // ref per skr
                              require(gem.transfer(tap, jam));
                          }
                          function flow() public note auth {
                              require(off);
                              out = true;
                          }
                      }

                      File 7 of 9: DSChief
                      // hevm: flattened sources of src/chief.sol
                      pragma solidity >=0.4.23;
                      
                      ////// lib/ds-roles/lib/ds-auth/src/auth.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.4.23; */
                      
                      contract DSAuthority {
                          function canCall(
                              address src, address dst, bytes4 sig
                          ) public view returns (bool);
                      }
                      
                      contract DSAuthEvents {
                          event LogSetAuthority (address indexed authority);
                          event LogSetOwner     (address indexed owner);
                      }
                      
                      contract DSAuth is DSAuthEvents {
                          DSAuthority  public  authority;
                          address      public  owner;
                      
                          constructor() public {
                              owner = msg.sender;
                              emit LogSetOwner(msg.sender);
                          }
                      
                          function setOwner(address owner_)
                              public
                              auth
                          {
                              owner = owner_;
                              emit LogSetOwner(owner);
                          }
                      
                          function setAuthority(DSAuthority authority_)
                              public
                              auth
                          {
                              authority = authority_;
                              emit LogSetAuthority(address(authority));
                          }
                      
                          modifier auth {
                              require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized");
                              _;
                          }
                      
                          function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
                              if (src == address(this)) {
                                  return true;
                              } else if (src == owner) {
                                  return true;
                              } else if (authority == DSAuthority(0)) {
                                  return false;
                              } else {
                                  return authority.canCall(src, address(this), sig);
                              }
                          }
                      }
                      
                      ////// lib/ds-roles/src/roles.sol
                      // roles.sol - roled based authentication
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.23; */
                      
                      /* import 'ds-auth/auth.sol'; */
                      
                      contract DSRoles is DSAuth, DSAuthority
                      {
                          mapping(address=>bool) _root_users;
                          mapping(address=>bytes32) _user_roles;
                          mapping(address=>mapping(bytes4=>bytes32)) _capability_roles;
                          mapping(address=>mapping(bytes4=>bool)) _public_capabilities;
                      
                          function getUserRoles(address who)
                              public
                              view
                              returns (bytes32)
                          {
                              return _user_roles[who];
                          }
                      
                          function getCapabilityRoles(address code, bytes4 sig)
                              public
                              view
                              returns (bytes32)
                          {
                              return _capability_roles[code][sig];
                          }
                      
                          function isUserRoot(address who)
                              public
                              view
                              returns (bool)
                          {
                              return _root_users[who];
                          }
                      
                          function isCapabilityPublic(address code, bytes4 sig)
                              public
                              view
                              returns (bool)
                          {
                              return _public_capabilities[code][sig];
                          }
                      
                          function hasUserRole(address who, uint8 role)
                              public
                              view
                              returns (bool)
                          {
                              bytes32 roles = getUserRoles(who);
                              bytes32 shifted = bytes32(uint256(uint256(2) ** uint256(role)));
                              return bytes32(0) != roles & shifted;
                          }
                      
                          function canCall(address caller, address code, bytes4 sig)
                              public
                              view
                              returns (bool)
                          {
                              if( isUserRoot(caller) || isCapabilityPublic(code, sig) ) {
                                  return true;
                              } else {
                                  bytes32 has_roles = getUserRoles(caller);
                                  bytes32 needs_one_of = getCapabilityRoles(code, sig);
                                  return bytes32(0) != has_roles & needs_one_of;
                              }
                          }
                      
                          function BITNOT(bytes32 input) internal pure returns (bytes32 output) {
                              return (input ^ bytes32(uint(-1)));
                          }
                      
                          function setRootUser(address who, bool enabled)
                              public
                              auth
                          {
                              _root_users[who] = enabled;
                          }
                      
                          function setUserRole(address who, uint8 role, bool enabled)
                              public
                              auth
                          {
                              bytes32 last_roles = _user_roles[who];
                              bytes32 shifted = bytes32(uint256(uint256(2) ** uint256(role)));
                              if( enabled ) {
                                  _user_roles[who] = last_roles | shifted;
                              } else {
                                  _user_roles[who] = last_roles & BITNOT(shifted);
                              }
                          }
                      
                          function setPublicCapability(address code, bytes4 sig, bool enabled)
                              public
                              auth
                          {
                              _public_capabilities[code][sig] = enabled;
                          }
                      
                          function setRoleCapability(uint8 role, address code, bytes4 sig, bool enabled)
                              public
                              auth
                          {
                              bytes32 last_roles = _capability_roles[code][sig];
                              bytes32 shifted = bytes32(uint256(uint256(2) ** uint256(role)));
                              if( enabled ) {
                                  _capability_roles[code][sig] = last_roles | shifted;
                              } else {
                                  _capability_roles[code][sig] = last_roles & BITNOT(shifted);
                              }
                      
                          }
                      
                      }
                      
                      ////// lib/ds-thing/lib/ds-math/src/math.sol
                      /// math.sol -- mixin for inline numerical wizardry
                      
                      // 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.4.13; */
                      
                      contract DSMath {
                          function add(uint x, uint y) internal pure returns (uint z) {
                              require((z = x + y) >= x, "ds-math-add-overflow");
                          }
                          function sub(uint x, uint y) internal pure returns (uint z) {
                              require((z = x - y) <= x, "ds-math-sub-underflow");
                          }
                          function mul(uint x, uint y) internal pure returns (uint z) {
                              require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
                          }
                      
                          function min(uint x, uint y) internal pure returns (uint z) {
                              return x <= y ? x : y;
                          }
                          function max(uint x, uint y) internal pure returns (uint z) {
                              return x >= y ? x : y;
                          }
                          function imin(int x, int y) internal pure returns (int z) {
                              return x <= y ? x : y;
                          }
                          function imax(int x, int y) internal pure returns (int z) {
                              return x >= y ? x : y;
                          }
                      
                          uint constant WAD = 10 ** 18;
                          uint constant RAY = 10 ** 27;
                      
                          function wmul(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, y), WAD / 2) / WAD;
                          }
                          function rmul(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, y), RAY / 2) / RAY;
                          }
                          function wdiv(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, WAD), y / 2) / y;
                          }
                          function rdiv(uint x, uint y) internal pure returns (uint z) {
                              z = add(mul(x, RAY), y / 2) / y;
                          }
                      
                          // This famous algorithm is called "exponentiation by squaring"
                          // and calculates x^n with x as fixed-point and n as regular unsigned.
                          //
                          // It's O(log n), instead of O(n) for naive repeated multiplication.
                          //
                          // These facts are why it works:
                          //
                          //  If n is even, then x^n = (x^2)^(n/2).
                          //  If n is odd,  then x^n = x * x^(n-1),
                          //   and applying the equation for even x gives
                          //    x^n = x * (x^2)^((n-1) / 2).
                          //
                          //  Also, EVM division is flooring and
                          //    floor[(n-1) / 2] = floor[n / 2].
                          //
                          function rpow(uint x, uint n) internal pure returns (uint z) {
                              z = n % 2 != 0 ? x : RAY;
                      
                              for (n /= 2; n != 0; n /= 2) {
                                  x = rmul(x, x);
                      
                                  if (n % 2 != 0) {
                                      z = rmul(z, x);
                                  }
                              }
                          }
                      }
                      
                      ////// lib/ds-thing/lib/ds-note/src/note.sol
                      /// note.sol -- the `note' modifier, for logging calls as events
                      
                      // 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.4.23; */
                      
                      contract DSNote {
                          event LogNote(
                              bytes4   indexed  sig,
                              address  indexed  guy,
                              bytes32  indexed  foo,
                              bytes32  indexed  bar,
                              uint256           wad,
                              bytes             fax
                          ) anonymous;
                      
                          modifier note {
                              bytes32 foo;
                              bytes32 bar;
                              uint256 wad;
                      
                              assembly {
                                  foo := calldataload(4)
                                  bar := calldataload(36)
                                  wad := callvalue
                              }
                      
                              emit LogNote(msg.sig, msg.sender, foo, bar, wad, msg.data);
                      
                              _;
                          }
                      }
                      
                      ////// lib/ds-thing/src/thing.sol
                      // thing.sol - `auth` with handy mixins. your things should be DSThings
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.23; */
                      
                      /* import 'ds-auth/auth.sol'; */
                      /* import 'ds-note/note.sol'; */
                      /* import 'ds-math/math.sol'; */
                      
                      contract DSThing is DSAuth, DSNote, DSMath {
                          function S(string memory s) internal pure returns (bytes4) {
                              return bytes4(keccak256(abi.encodePacked(s)));
                          }
                      
                      }
                      
                      ////// lib/ds-token/lib/ds-stop/src/stop.sol
                      /// stop.sol -- mixin for enable/disable functionality
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.23; */
                      
                      /* import "ds-auth/auth.sol"; */
                      /* import "ds-note/note.sol"; */
                      
                      contract DSStop is DSNote, DSAuth {
                          bool public stopped;
                      
                          modifier stoppable {
                              require(!stopped, "ds-stop-is-stopped");
                              _;
                          }
                          function stop() public auth note {
                              stopped = true;
                          }
                          function start() public auth note {
                              stopped = false;
                          }
                      
                      }
                      
                      ////// lib/ds-token/lib/erc20/src/erc20.sol
                      /// erc20.sol -- API for the ERC20 token standard
                      
                      // See <https://github.com/ethereum/EIPs/issues/20>.
                      
                      // This file likely does not meet the threshold of originality
                      // required for copyright to apply.  As a result, this is free and
                      // unencumbered software belonging to the public domain.
                      
                      /* pragma solidity >0.4.20; */
                      
                      contract ERC20Events {
                          event Approval(address indexed src, address indexed guy, uint wad);
                          event Transfer(address indexed src, address indexed dst, uint wad);
                      }
                      
                      contract ERC20 is ERC20Events {
                          function totalSupply() public view returns (uint);
                          function balanceOf(address guy) public view returns (uint);
                          function allowance(address src, address guy) public view returns (uint);
                      
                          function approve(address guy, uint wad) public returns (bool);
                          function transfer(address dst, uint wad) public returns (bool);
                          function transferFrom(
                              address src, address dst, uint wad
                          ) public returns (bool);
                      }
                      
                      ////// lib/ds-token/src/base.sol
                      /// base.sol -- basic ERC20 implementation
                      
                      // Copyright (C) 2015, 2016, 2017  DappHub, LLC
                      
                      // 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.4.23; */
                      
                      /* import "erc20/erc20.sol"; */
                      /* import "ds-math/math.sol"; */
                      
                      contract DSTokenBase is ERC20, DSMath {
                          uint256                                            _supply;
                          mapping (address => uint256)                       _balances;
                          mapping (address => mapping (address => uint256))  _approvals;
                      
                          constructor(uint supply) public {
                              _balances[msg.sender] = supply;
                              _supply = supply;
                          }
                      
                          function totalSupply() public view returns (uint) {
                              return _supply;
                          }
                          function balanceOf(address src) public view returns (uint) {
                              return _balances[src];
                          }
                          function allowance(address src, address guy) public view returns (uint) {
                              return _approvals[src][guy];
                          }
                      
                          function transfer(address dst, uint wad) public returns (bool) {
                              return transferFrom(msg.sender, dst, wad);
                          }
                      
                          function transferFrom(address src, address dst, uint wad)
                              public
                              returns (bool)
                          {
                              if (src != msg.sender) {
                                  require(_approvals[src][msg.sender] >= wad, "ds-token-insufficient-approval");
                                  _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
                              }
                      
                              require(_balances[src] >= wad, "ds-token-insufficient-balance");
                              _balances[src] = sub(_balances[src], wad);
                              _balances[dst] = add(_balances[dst], wad);
                      
                              emit Transfer(src, dst, wad);
                      
                              return true;
                          }
                      
                          function approve(address guy, uint wad) public returns (bool) {
                              _approvals[msg.sender][guy] = wad;
                      
                              emit Approval(msg.sender, guy, wad);
                      
                              return true;
                          }
                      }
                      
                      ////// lib/ds-token/src/token.sol
                      /// token.sol -- ERC20 implementation with minting and burning
                      
                      // Copyright (C) 2015, 2016, 2017  DappHub, LLC
                      
                      // 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.4.23; */
                      
                      /* import "ds-stop/stop.sol"; */
                      
                      /* import "./base.sol"; */
                      
                      contract DSToken is DSTokenBase(0), DSStop {
                      
                          bytes32  public  symbol;
                          uint256  public  decimals = 18; // standard token precision. override to customize
                      
                          constructor(bytes32 symbol_) public {
                              symbol = symbol_;
                          }
                      
                          event Mint(address indexed guy, uint wad);
                          event Burn(address indexed guy, uint wad);
                      
                          function approve(address guy) public stoppable returns (bool) {
                              return super.approve(guy, uint(-1));
                          }
                      
                          function approve(address guy, uint wad) public stoppable returns (bool) {
                              return super.approve(guy, wad);
                          }
                      
                          function transferFrom(address src, address dst, uint wad)
                              public
                              stoppable
                              returns (bool)
                          {
                              if (src != msg.sender && _approvals[src][msg.sender] != uint(-1)) {
                                  require(_approvals[src][msg.sender] >= wad, "ds-token-insufficient-approval");
                                  _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad);
                              }
                      
                              require(_balances[src] >= wad, "ds-token-insufficient-balance");
                              _balances[src] = sub(_balances[src], wad);
                              _balances[dst] = add(_balances[dst], wad);
                      
                              emit Transfer(src, dst, wad);
                      
                              return true;
                          }
                      
                          function push(address dst, uint wad) public {
                              transferFrom(msg.sender, dst, wad);
                          }
                          function pull(address src, uint wad) public {
                              transferFrom(src, msg.sender, wad);
                          }
                          function move(address src, address dst, uint wad) public {
                              transferFrom(src, dst, wad);
                          }
                      
                          function mint(uint wad) public {
                              mint(msg.sender, wad);
                          }
                          function burn(uint wad) public {
                              burn(msg.sender, wad);
                          }
                          function mint(address guy, uint wad) public auth stoppable {
                              _balances[guy] = add(_balances[guy], wad);
                              _supply = add(_supply, wad);
                              emit Mint(guy, wad);
                          }
                          function burn(address guy, uint wad) public auth stoppable {
                              if (guy != msg.sender && _approvals[guy][msg.sender] != uint(-1)) {
                                  require(_approvals[guy][msg.sender] >= wad, "ds-token-insufficient-approval");
                                  _approvals[guy][msg.sender] = sub(_approvals[guy][msg.sender], wad);
                              }
                      
                              require(_balances[guy] >= wad, "ds-token-insufficient-balance");
                              _balances[guy] = sub(_balances[guy], wad);
                              _supply = sub(_supply, wad);
                              emit Burn(guy, wad);
                          }
                      
                          // Optional token name
                          bytes32   public  name = "";
                      
                          function setName(bytes32 name_) public auth {
                              name = name_;
                          }
                      }
                      
                      ////// src/chief.sol
                      // chief.sol - select an authority by consensus
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.23; */
                      
                      /* import 'ds-token/token.sol'; */
                      /* import 'ds-roles/roles.sol'; */
                      /* import 'ds-thing/thing.sol'; */
                      
                      // The right way to use this contract is probably to mix it with some kind
                      // of `DSAuthority`, like with `ds-roles`.
                      //   SEE DSChief
                      contract DSChiefApprovals is DSThing {
                          mapping(bytes32=>address[]) public slates;
                          mapping(address=>bytes32) public votes;
                          mapping(address=>uint256) public approvals;
                          mapping(address=>uint256) public deposits;
                          DSToken public GOV; // voting token that gets locked up
                          DSToken public IOU; // non-voting representation of a token, for e.g. secondary voting mechanisms
                          address public hat; // the chieftain's hat
                      
                          uint256 public MAX_YAYS;
                      
                          event Etch(bytes32 indexed slate);
                      
                          // IOU constructed outside this contract reduces deployment costs significantly
                          // lock/free/vote are quite sensitive to token invariants. Caution is advised.
                          constructor(DSToken GOV_, DSToken IOU_, uint MAX_YAYS_) public
                          {
                              GOV = GOV_;
                              IOU = IOU_;
                              MAX_YAYS = MAX_YAYS_;
                          }
                      
                          function lock(uint wad)
                              public
                              note
                          {
                              GOV.pull(msg.sender, wad);
                              IOU.mint(msg.sender, wad);
                              deposits[msg.sender] = add(deposits[msg.sender], wad);
                              addWeight(wad, votes[msg.sender]);
                          }
                      
                          function free(uint wad)
                              public
                              note
                          {
                              deposits[msg.sender] = sub(deposits[msg.sender], wad);
                              subWeight(wad, votes[msg.sender]);
                              IOU.burn(msg.sender, wad);
                              GOV.push(msg.sender, wad);
                          }
                      
                          function etch(address[] memory yays)
                              public
                              note
                              returns (bytes32 slate)
                          {
                              require( yays.length <= MAX_YAYS );
                              requireByteOrderedSet(yays);
                      
                              bytes32 hash = keccak256(abi.encodePacked(yays));
                              slates[hash] = yays;
                              emit Etch(hash);
                              return hash;
                          }
                      
                          function vote(address[] memory yays) public returns (bytes32)
                              // note  both sub-calls note
                          {
                              bytes32 slate = etch(yays);
                              vote(slate);
                              return slate;
                          }
                      
                          function vote(bytes32 slate)
                              public
                              note
                          {
                              require(slates[slate].length > 0 || 
                                  slate == 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470, "ds-chief-invalid-slate");
                              uint weight = deposits[msg.sender];
                              subWeight(weight, votes[msg.sender]);
                              votes[msg.sender] = slate;
                              addWeight(weight, votes[msg.sender]);
                          }
                      
                          // like `drop`/`swap` except simply "elect this address if it is higher than current hat"
                          function lift(address whom)
                              public
                              note
                          {
                              require(approvals[whom] > approvals[hat]);
                              hat = whom;
                          }
                      
                          function addWeight(uint weight, bytes32 slate)
                              internal
                          {
                              address[] storage yays = slates[slate];
                              for( uint i = 0; i < yays.length; i++) {
                                  approvals[yays[i]] = add(approvals[yays[i]], weight);
                              }
                          }
                      
                          function subWeight(uint weight, bytes32 slate)
                              internal
                          {
                              address[] storage yays = slates[slate];
                              for( uint i = 0; i < yays.length; i++) {
                                  approvals[yays[i]] = sub(approvals[yays[i]], weight);
                              }
                          }
                      
                          // Throws unless the array of addresses is a ordered set.
                          function requireByteOrderedSet(address[] memory yays)
                              internal
                              pure
                          {
                              if( yays.length == 0 || yays.length == 1 ) {
                                  return;
                              }
                              for( uint i = 0; i < yays.length - 1; i++ ) {
                                  // strict inequality ensures both ordering and uniqueness
                                  require(uint(yays[i]) < uint(yays[i+1]));
                              }
                          }
                      }
                      
                      
                      // `hat` address is unique root user (has every role) and the
                      // unique owner of role 0 (typically 'sys' or 'internal')
                      contract DSChief is DSRoles, DSChiefApprovals {
                      
                          constructor(DSToken GOV, DSToken IOU, uint MAX_YAYS)
                                   DSChiefApprovals (GOV, IOU, MAX_YAYS)
                              public
                          {
                              authority = this;
                              owner = address(0);
                          }
                      
                          function setOwner(address owner_) public {
                              owner_;
                              revert();
                          }
                      
                          function setAuthority(DSAuthority authority_) public {
                              authority_;
                              revert();
                          }
                      
                          function isUserRoot(address who)
                              public view
                              returns (bool)
                          {
                              return (who == hat);
                          }
                          function setRootUser(address who, bool enabled) public {
                              who; enabled;
                              revert();
                          }
                      }

                      File 8 of 9: DSPauseProxy
                      // hevm: flattened sources of /nix/store/b2bvh9ljr3yljrdz6lm764hdyj7nk4iy-ds-pause-f43edc1/src/pause.sol
                      pragma solidity >=0.4.23 >=0.5.0 <0.6.0;
                      
                      ////// /nix/store/6qq1ps6wrikrl6ha3q33739dbs2wg2hb-ds-note/dapp/ds-note/src/note.sol
                      /// note.sol -- the `note' modifier, for logging calls as events
                      
                      // 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.4.23; */
                      
                      contract DSNote {
                          event LogNote(
                              bytes4   indexed  sig,
                              address  indexed  guy,
                              bytes32  indexed  foo,
                              bytes32  indexed  bar,
                              uint256           wad,
                              bytes             fax
                          ) anonymous;
                      
                          modifier note {
                              bytes32 foo;
                              bytes32 bar;
                              uint256 wad;
                      
                              assembly {
                                  foo := calldataload(4)
                                  bar := calldataload(36)
                                  wad := callvalue
                              }
                      
                              emit LogNote(msg.sig, msg.sender, foo, bar, wad, msg.data);
                      
                              _;
                          }
                      }
                      
                      ////// /nix/store/r1w3fgb8wh0c2qn0i8jg95sv99l5nh7j-ds-auth/dapp/ds-auth/src/auth.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.4.23; */
                      
                      contract DSAuthority {
                          function canCall(
                              address src, address dst, bytes4 sig
                          ) public view returns (bool);
                      }
                      
                      contract DSAuthEvents {
                          event LogSetAuthority (address indexed authority);
                          event LogSetOwner     (address indexed owner);
                      }
                      
                      contract DSAuth is DSAuthEvents {
                          DSAuthority  public  authority;
                          address      public  owner;
                      
                          constructor() public {
                              owner = msg.sender;
                              emit LogSetOwner(msg.sender);
                          }
                      
                          function setOwner(address owner_)
                              public
                              auth
                          {
                              owner = owner_;
                              emit LogSetOwner(owner);
                          }
                      
                          function setAuthority(DSAuthority authority_)
                              public
                              auth
                          {
                              authority = authority_;
                              emit LogSetAuthority(address(authority));
                          }
                      
                          modifier auth {
                              require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized");
                              _;
                          }
                      
                          function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
                              if (src == address(this)) {
                                  return true;
                              } else if (src == owner) {
                                  return true;
                              } else if (authority == DSAuthority(0)) {
                                  return false;
                              } else {
                                  return authority.canCall(src, address(this), sig);
                              }
                          }
                      }
                      
                      ////// /nix/store/b2bvh9ljr3yljrdz6lm764hdyj7nk4iy-ds-pause-f43edc1/src/pause.sol
                      // Copyright (C) 2019 David Terry <[email protected]>
                      //
                      // 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.0 <0.6.0; */
                      
                      /* import {DSNote} from "ds-note/note.sol"; */
                      /* import {DSAuth, DSAuthority} from "ds-auth/auth.sol"; */
                      
                      contract DSPause is DSAuth, DSNote {
                      
                          // --- admin ---
                      
                          modifier wait { require(msg.sender == address(proxy), "ds-pause-undelayed-call"); _; }
                      
                          function setOwner(address owner_) public wait {
                              owner = owner_;
                              emit LogSetOwner(owner);
                          }
                          function setAuthority(DSAuthority authority_) public wait {
                              authority = authority_;
                              emit LogSetAuthority(address(authority));
                          }
                          function setDelay(uint delay_) public note wait {
                              delay = delay_;
                          }
                      
                          // --- math ---
                      
                          function add(uint x, uint y) internal pure returns (uint z) {
                              z = x + y;
                              require(z >= x, "ds-pause-addition-overflow");
                          }
                      
                          // --- data ---
                      
                          mapping (bytes32 => bool) public plans;
                          DSPauseProxy public proxy;
                          uint         public delay;
                      
                          // --- init ---
                      
                          constructor(uint delay_, address owner_, DSAuthority authority_) public {
                              delay = delay_;
                              owner = owner_;
                              authority = authority_;
                              proxy = new DSPauseProxy();
                          }
                      
                          // --- util ---
                      
                          function hash(address usr, bytes32 tag, bytes memory fax, uint eta)
                              internal pure
                              returns (bytes32)
                          {
                              return keccak256(abi.encode(usr, tag, fax, eta));
                          }
                      
                          function soul(address usr)
                              internal view
                              returns (bytes32 tag)
                          {
                              assembly { tag := extcodehash(usr) }
                          }
                      
                          // --- operations ---
                      
                          function plot(address usr, bytes32 tag, bytes memory fax, uint eta)
                              public note auth
                          {
                              require(eta >= add(now, delay), "ds-pause-delay-not-respected");
                              plans[hash(usr, tag, fax, eta)] = true;
                          }
                      
                          function drop(address usr, bytes32 tag, bytes memory fax, uint eta)
                              public note auth
                          {
                              plans[hash(usr, tag, fax, eta)] = false;
                          }
                      
                          function exec(address usr, bytes32 tag, bytes memory fax, uint eta)
                              public note
                              returns (bytes memory out)
                          {
                              require(plans[hash(usr, tag, fax, eta)], "ds-pause-unplotted-plan");
                              require(soul(usr) == tag,                "ds-pause-wrong-codehash");
                              require(now >= eta,                      "ds-pause-premature-exec");
                      
                              plans[hash(usr, tag, fax, eta)] = false;
                      
                              out = proxy.exec(usr, fax);
                              require(proxy.owner() == address(this), "ds-pause-illegal-storage-change");
                          }
                      }
                      
                      // plans are executed in an isolated storage context to protect the pause from
                      // malicious storage modification during plan execution
                      contract DSPauseProxy {
                          address public owner;
                          modifier auth { require(msg.sender == owner, "ds-pause-proxy-unauthorized"); _; }
                          constructor() public { owner = msg.sender; }
                      
                          function exec(address usr, bytes memory fax)
                              public auth
                              returns (bytes memory out)
                          {
                              bool ok;
                              (ok, out) = usr.delegatecall(fax);
                              require(ok, "ds-pause-delegatecall-error");
                          }
                      }

                      File 9 of 9: DSGuard
                      // hevm: flattened sources of src/guard.sol
                      pragma solidity ^0.4.13;
                      
                      ////// lib/ds-auth/src/auth.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.4.13; */
                      
                      contract DSAuthority {
                          function canCall(
                              address src, address dst, bytes4 sig
                          ) public view returns (bool);
                      }
                      
                      contract DSAuthEvents {
                          event LogSetAuthority (address indexed authority);
                          event LogSetOwner     (address indexed owner);
                      }
                      
                      contract DSAuth is DSAuthEvents {
                          DSAuthority  public  authority;
                          address      public  owner;
                      
                          function DSAuth() public {
                              owner = msg.sender;
                              LogSetOwner(msg.sender);
                          }
                      
                          function setOwner(address owner_)
                              public
                              auth
                          {
                              owner = owner_;
                              LogSetOwner(owner);
                          }
                      
                          function setAuthority(DSAuthority authority_)
                              public
                              auth
                          {
                              authority = authority_;
                              LogSetAuthority(authority);
                          }
                      
                          modifier auth {
                              require(isAuthorized(msg.sender, msg.sig));
                              _;
                          }
                      
                          function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
                              if (src == address(this)) {
                                  return true;
                              } else if (src == owner) {
                                  return true;
                              } else if (authority == DSAuthority(0)) {
                                  return false;
                              } else {
                                  return authority.canCall(src, this, sig);
                              }
                          }
                      }
                      
                      ////// src/guard.sol
                      // guard.sol -- simple whitelist implementation of DSAuthority
                      
                      // Copyright (C) 2017  DappHub, LLC
                      
                      // 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.4.13; */
                      
                      /* import "ds-auth/auth.sol"; */
                      
                      contract DSGuardEvents {
                          event LogPermit(
                              bytes32 indexed src,
                              bytes32 indexed dst,
                              bytes32 indexed sig
                          );
                      
                          event LogForbid(
                              bytes32 indexed src,
                              bytes32 indexed dst,
                              bytes32 indexed sig
                          );
                      }
                      
                      contract DSGuard is DSAuth, DSAuthority, DSGuardEvents {
                          bytes32 constant public ANY = bytes32(uint(-1));
                      
                          mapping (bytes32 => mapping (bytes32 => mapping (bytes32 => bool))) acl;
                      
                          function canCall(
                              address src_, address dst_, bytes4 sig
                          ) public view returns (bool) {
                              var src = bytes32(src_);
                              var dst = bytes32(dst_);
                      
                              return acl[src][dst][sig]
                                  || acl[src][dst][ANY]
                                  || acl[src][ANY][sig]
                                  || acl[src][ANY][ANY]
                                  || acl[ANY][dst][sig]
                                  || acl[ANY][dst][ANY]
                                  || acl[ANY][ANY][sig]
                                  || acl[ANY][ANY][ANY];
                          }
                      
                          function permit(bytes32 src, bytes32 dst, bytes32 sig) public auth {
                              acl[src][dst][sig] = true;
                              LogPermit(src, dst, sig);
                          }
                      
                          function forbid(bytes32 src, bytes32 dst, bytes32 sig) public auth {
                              acl[src][dst][sig] = false;
                              LogForbid(src, dst, sig);
                          }
                      
                          function permit(address src, address dst, bytes32 sig) public {
                              permit(bytes32(src), bytes32(dst), sig);
                          }
                          function forbid(address src, address dst, bytes32 sig) public {
                              forbid(bytes32(src), bytes32(dst), sig);
                          }
                      
                      }
                      
                      contract DSGuardFactory {
                          mapping (address => bool)  public  isGuard;
                      
                          function newGuard() public returns (DSGuard guard) {
                              guard = new DSGuard();
                              guard.setOwner(msg.sender);
                              isGuard[guard] = true;
                          }
                      }