ETH Price: $2,557.82 (+1.63%)

Transaction Decoder

Block:
11233224 at Nov-11-2020 01:06:06 AM +UTC
Transaction Fee:
0.00421504 ETH $10.78
Gas Used:
105,376 Gas / 40 Gwei

Emitted Events:

178 SaiTub.0x40cc885400000000000000000000000000000000000000000000000000000000( 0x40cc885400000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000007728d2b25371c2646fd87d28ade7c5fb0a48b753, 0x000000000000000000000000000000000000000000000000000000000000606d, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 0000000000000000000000000000000000000000000000000000002440cc8854, 000000000000000000000000000000000000000000000000000000000000606d )
179 SaiVox.0x495d32cb00000000000000000000000000000000000000000000000000000000( 0x495d32cb00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000448a5065aebb8e423f0896e6c5d525c040f59af3, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 00000000000000000000000000000000000000000000000000000004495d32cb )
180 SaiTub.0x40cc885400000000000000000000000000000000000000000000000000000000( 0x40cc885400000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000007728d2b25371c2646fd87d28ade7c5fb0a48b753, 0x000000000000000000000000000000000000000000000000000000000000606d, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 0000000000000000000000000000000000000000000000000000002440cc8854, 000000000000000000000000000000000000000000000000000000000000606d )
181 SaiTub.0x40cc885400000000000000000000000000000000000000000000000000000000( 0x40cc885400000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000007728d2b25371c2646fd87d28ade7c5fb0a48b753, 0x000000000000000000000000000000000000000000000000000000000000606d, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 0000000000000000000000000000000000000000000000000000002440cc8854, 000000000000000000000000000000000000000000000000000000000000606d )
182 DSToken.Mint( guy=SaiTap, wad=10000000000000000 )
183 SaiVox.0x495d32cb00000000000000000000000000000000000000000000000000000000( 0x495d32cb00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000448a5065aebb8e423f0896e6c5d525c040f59af3, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 00000000000000000000000000000000000000000000000000000004495d32cb )
184 DSToken.Transfer( src=[Receiver] SaiTub, dst=SaiTap, wad=50251942365699 )

Account State Difference:

  Address   Before After State Difference Code
0x448a5065...040f59af3
(Sky: Contract 1)
0x7728d2B2...B0A48b753
0.011196021 Eth
Nonce: 11
0.006980981 Eth
Nonce: 12
0.00421504
0x79F6D0f6...f357d4680
(F2Pool Old)
5,963.209638014149434006 Eth5,963.213853054149434006 Eth0.00421504
0x9B0F70Df...EA77f2d7A
(Sky: Contract 3)
0xf53AD2c6...1B2321C09

Execution Trace

SaiTub.bite( cup=000000000000000000000000000000000000000000000000000000000000606D )
  • SaiVox.CALL( )
  • DSToken.mint( guy=0xBda109309f9FafA6Dd6A9CB9f1Df4085B27Ee8eF, wad=10000000000000000 )
    • DSGuard.canCall( src_=0x448a5065aeBB8E423F0896E6c5D525C040f59af3, dst_=0x79F6D0f646706E1261aCF0b93DCB864f357d4680, sig=System.Byte[] ) => ( True )
    • SaiVox.CALL( )
    • DSToken.push( dst=0xBda109309f9FafA6Dd6A9CB9f1Df4085B27Ee8eF, wad=50251942365699 )
      File 1 of 6: 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 2 of 6: SaiVox
      // hevm: flattened sources of src/vox.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));
          }
      
      }
      
      ////// 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));
          }
      }

      File 3 of 6: DSToken
      pragma solidity ^0.4.13;
      
      ////// 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-stop/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-stop/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-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/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);
      }
      
      ////// 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;
          }
      }
      
      ////// 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_;
          }
      }

      File 4 of 6: SaiTap
      // hevm: flattened sources of src/tap.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());
          }
      }

      File 5 of 6: DSToken
      pragma solidity ^0.4.13;
      
      ////// 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-stop/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-stop/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-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/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);
      }
      
      ////// 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;
          }
      }
      
      ////// 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_;
          }
      }

      File 6 of 6: 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;
          }
      }