false
true
0

Contract Address Details

0xbaa65281c2FA2baAcb2cb550BA051525A480D3F4

Contract Name
DssDeploy
Creator
0xddb108–617acc at 0xa4e10b–80634b
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
14 Transactions
Transfers
0 Transfers
Gas Used
30,735,161
Last Balance Update
25859318
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been partially verified via Sourcify. View contract in Sourcify repository
Contract name:
DssDeploy




Optimization enabled
true
Compiler version
v0.5.12+commit.7709ece9




Optimization runs
200
EVM Version
petersburg




Verified at
2026-02-04T12:47:09.261080Z

Constructor Arguments

000000000000000000000000403689148fa98a5a6fdcc0b984914ae968d788e500000000000000000000000045f0a929889ec8cc2d5b8cd79ab55e3279945cde00000000000000000000000068322ca1a9aeb8c1d610b5fc8a8920aa0fba423b000000000000000000000000a9ee75d81d78c36c4163004e6cc7a988eec9433e000000000000000000000000b5b06a16621616875a6c2637948bf98ea57c58fa00000000000000000000000064a84e558192dd025f3a96775fee8fb530f27177000000000000000000000000d27a5f3416d8791fc238c148c93630d9e3c882e5000000000000000000000000c41c4759f67ff54c7a7314d155f40fc6504f5d28000000000000000000000000bab4fbea257abbfe84f4588d4eedc43656e46fc5000000000000000000000000dedd12bcb045c02b2fe11031c2b269bcde4574100000000000000000000000001a5ee7c64cf874c735968e3a42fa13f1c03427f9000000000000000000000000fd34e2c588a519f173d54be539a56fed4830ba530000000000000000000000002e278c5fb9231581f4284a253cc5728b6acd372d00000000000000000000000084f2b4648990d93c0f478d5d82d3c38d98a4ee91

Arg [0] (address) : 0x403689148fa98a5a6fdcc0b984914ae968d788e5
Arg [1] (address) : 0x45f0a929889ec8cc2d5b8cd79ab55e3279945cde
Arg [2] (address) : 0x68322ca1a9aeb8c1d610b5fc8a8920aa0fba423b
Arg [3] (address) : 0xa9ee75d81d78c36c4163004e6cc7a988eec9433e
Arg [4] (address) : 0xb5b06a16621616875a6c2637948bf98ea57c58fa
Arg [5] (address) : 0x64a84e558192dd025f3a96775fee8fb530f27177
Arg [6] (address) : 0xd27a5f3416d8791fc238c148c93630d9e3c882e5
Arg [7] (address) : 0xc41c4759f67ff54c7a7314d155f40fc6504f5d28
Arg [8] (address) : 0xbab4fbea257abbfe84f4588d4eedc43656e46fc5
Arg [9] (address) : 0xdedd12bcb045c02b2fe11031c2b269bcde457410
Arg [10] (address) : 0x1a5ee7c64cf874c735968e3a42fa13f1c03427f9
Arg [11] (address) : 0xfd34e2c588a519f173d54be539a56fed4830ba53
Arg [12] (address) : 0x2e278c5fb9231581f4284a253cc5728b6acd372d
Arg [13] (address) : 0x84f2b4648990d93c0f478d5d82d3c38d98a4ee91

              

DssDeploy.sol

pragma solidity ^0.5.12;

contract VatFab {
    function newVat() public returns (Vat vat) {
        vat = new Vat();
        vat.rely(msg.sender);
        vat.deny(address(this));
    }
}

contract JugFab {
    function newJug(address vat) public returns (Jug jug) {
        jug = new Jug(vat);
        jug.rely(msg.sender);
        jug.deny(address(this));
    }
}

contract VowFab {
    function newVow(address vat, address flap, address flop) public returns (Vow vow) {
        vow = new Vow(vat, flap, flop);
        vow.rely(msg.sender);
        vow.deny(address(this));
    }
}

contract CatFab {
    function newCat(address vat) public returns (Cat cat) {
        cat = new Cat(vat);
        cat.rely(msg.sender);
        cat.deny(address(this));
    }
}

contract DaiFab {
    function newDai(uint chainId) public returns (Dai dai) {
        dai = new Dai(chainId);
        dai.rely(msg.sender);
        dai.deny(address(this));
    }
}

contract DaiJoinFab {
    function newDaiJoin(address vat, address dai) public returns (DaiJoin daiJoin) {
        daiJoin = new DaiJoin(vat, dai);
    }
}

contract FlapFab {
    function newFlap(address vat, address gov) public returns (Flapper flap) {
        flap = new Flapper(vat, gov);
        flap.rely(msg.sender);
        flap.deny(address(this));
    }
}

contract FlopFab {
    function newFlop(address vat, address gov) public returns (Flopper flop) {
        flop = new Flopper(vat, gov);
        flop.rely(msg.sender);
        flop.deny(address(this));
    }
}

contract FlipFab {
    function newFlip(address vat, bytes32 ilk) public returns (Flipper flip) {
        flip = new Flipper(vat, ilk);
        flip.rely(msg.sender);
        flip.deny(address(this));
    }
}

contract SpotFab {
    function newSpotter(address vat) public returns (Spotter spotter) {
        spotter = new Spotter(vat);
        spotter.rely(msg.sender);
        spotter.deny(address(this));
    }
}

contract PotFab {
    function newPot(address vat) public returns (Pot pot) {
        pot = new Pot(vat);
        pot.rely(msg.sender);
        pot.deny(address(this));
    }
}

contract EndFab {
    function newEnd() public returns (End end) {
        end = new End();
        end.rely(msg.sender);
        end.deny(address(this));
    }
}

contract ESMFab {
    function newESM(address gov, address end, address pit, uint min) public returns (ESM esm) {
        esm = new ESM(gov, end, pit, min);
    }
}

contract PauseFab {
    function newPause(uint delay, address owner, DSAuthority authority) public returns(DSPause pause) {
        pause = new DSPause(delay, owner, authority);
    }
}

contract GemLikeESM {
    function balanceOf(address) public view returns (uint256);
    function transfer(address, uint256) public returns (bool);
    function transferFrom(address, address, uint256) public returns (bool);
}

contract EndLike {
    function cage() public;
}

contract ESM {
    GemLikeESM public gem; // collateral
    EndLike public end; // cage module
    address public pit; // burner
    uint256 public min; // threshold
    uint256 public fired;

    mapping(address => uint256) public sum; // per-address balance
    uint256 public Sum; // total balance

    // --- Logs ---
    event LogNote(
        bytes4   indexed  sig,
        address  indexed  usr,
        bytes32  indexed  arg1,
        bytes32  indexed  arg2,
        bytes             data
    ) anonymous;

    modifier note {
        _;
        assembly {
            // log an 'anonymous' event with a constant 6 words of calldata
            // and four indexed topics: selector, caller, arg1 and arg2
            let mark := msize                         // end of memory ensures zero
            mstore(0x40, add(mark, 288))              // update free memory pointer
            mstore(mark, 0x20)                        // bytes type data offset
            mstore(add(mark, 0x20), 224)              // bytes size (padded)
            calldatacopy(add(mark, 0x40), 0, 224)     // bytes payload
            log4(mark, 288,                           // calldata
                 shl(224, shr(224, calldataload(0))), // msg.sig
                 caller,                              // msg.sender
                 calldataload(4),                     // arg1
                 calldataload(36)                     // arg2
                )
        }
    }

    constructor(address gem_, address end_, address pit_, uint256 min_) public {
        gem = GemLikeESM(gem_);
        end = EndLike(end_);
        pit = pit_;
        min = min_;
    }

    // -- math --
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x + y;
        require(z >= x);
    }

    function fire() external note {
        require(fired == 0,  "esm/already-fired");
        require(Sum >= min,  "esm/min-not-reached");

        end.cage();

        fired = 1;
    }

    function join(uint256 wad) external note {
        require(fired == 0, "esm/already-fired");

        sum[msg.sender] = add(sum[msg.sender], wad);
        Sum = add(Sum, wad);

        require(gem.transferFrom(msg.sender, pit, wad), "esm/transfer-failed");
    }
}

contract DSAuthority {
    function canCall(
        address src, address dst, bytes4 sig
    ) public view returns (bool);
}

contract DSAuthEvents {
    event LogSetAuthority (address indexed authority);
    event LogSetOwner     (address indexed owner);
}

contract DSAuth is DSAuthEvents {
    DSAuthority  public  authority;
    address      public  owner;

    constructor() public {
        owner = msg.sender;
        emit LogSetOwner(msg.sender);
    }

    function setOwner(address owner_)
        public
        auth
    {
        owner = owner_;
        emit LogSetOwner(owner);
    }

    function setAuthority(DSAuthority authority_)
        public
        auth
    {
        authority = authority_;
        emit LogSetAuthority(address(authority));
    }

    modifier auth {
        require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized");
        _;
    }

    function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
        if (src == address(this)) {
            return true;
        } else if (src == owner) {
            return true;
        } else if (authority == DSAuthority(0)) {
            return false;
        } else {
            return authority.canCall(src, address(this), sig);
        }
    }
}

contract DssDeploy is DSAuth {
    VatFab     public vatFab;
    JugFab     public jugFab;
    VowFab     public vowFab;
    CatFab     public catFab;
    DaiFab     public daiFab;
    DaiJoinFab public daiJoinFab;
    FlapFab    public flapFab;
    FlopFab    public flopFab;
    FlipFab    public flipFab;
    SpotFab    public spotFab;
    PotFab     public potFab;
    EndFab     public endFab;
    ESMFab     public esmFab;
    PauseFab   public pauseFab;

    Vat     public vat;
    Jug     public jug;
    Vow     public vow;
    Cat     public cat;
    Dai     public dai;
    DaiJoin public daiJoin;
    Flapper public flap;
    Flopper public flop;
    Spotter public spotter;
    Pot     public pot;
    End     public end;
    ESM     public esm;
    DSPause public pause;

    mapping(bytes32 => Ilk) public ilks;

    uint8 public step = 0;

    uint256 constant ONE = 10 ** 27;

    struct Ilk {
        Flipper flip;
        address join;
    }

    constructor(
        VatFab vatFab_,
        JugFab jugFab_,
        VowFab vowFab_,
        CatFab catFab_,
        DaiFab daiFab_,
        DaiJoinFab daiJoinFab_,
        FlapFab flapFab_,
        FlopFab flopFab_,
        FlipFab flipFab_,
        SpotFab spotFab_,
        PotFab potFab_,
        EndFab endFab_,
        ESMFab esmFab_,
        PauseFab pauseFab_
    ) public {
        vatFab = vatFab_;
        jugFab = jugFab_;
        vowFab = vowFab_;
        catFab = catFab_;
        daiFab = daiFab_;
        daiJoinFab = daiJoinFab_;
        flapFab = flapFab_;
        flopFab = flopFab_;
        flipFab = flipFab_;
        spotFab = spotFab_;
        potFab = potFab_;
        endFab = endFab_;
        esmFab = esmFab_;
        pauseFab = pauseFab_;
    }

    function rad(uint wad) internal pure returns (uint) {
        return wad * 10 ** 27;
    }

    function deployVat() public auth {
        require(address(vat) == address(0), "VAT already deployed");
        vat = vatFab.newVat();
        spotter = spotFab.newSpotter(address(vat));

        // Internal auth
        vat.rely(address(spotter));
    }

    function deployDai(uint256 chainId) public auth {
        require(address(vat) != address(0), "Missing previous step");

        // Deploy
        dai = daiFab.newDai(chainId);
        daiJoin = daiJoinFab.newDaiJoin(address(vat), address(dai));
        dai.rely(address(daiJoin));
    }

    function deployTaxation() public auth {
        require(address(vat) != address(0), "Missing previous step");

        // Deploy
        jug = jugFab.newJug(address(vat));
        pot = potFab.newPot(address(vat));

        // Internal auth
        vat.rely(address(jug));
        vat.rely(address(pot));
    }

    function deployAuctions(address gov) public auth {
        require(gov != address(0), "Missing GOV address");
        require(address(jug) != address(0), "Missing previous step");

        // Deploy
        flap = flapFab.newFlap(address(vat), gov);
        flop = flopFab.newFlop(address(vat), gov);
        vow = vowFab.newVow(address(vat), address(flap), address(flop));

        // Internal references set up
        jug.file("vow", address(vow));
        pot.file("vow", address(vow));

        // Internal auth
        flap.rely(address(vow));
        flop.rely(address(vow));
    }

    function deployLiquidator() public auth {
        require(address(vow) != address(0), "Missing previous step");

        // Deploy
        cat = catFab.newCat(address(vat));

        // Internal references set up
        cat.file("vow", address(vow));

        // Internal auth
        vat.rely(address(cat));
        vow.rely(address(cat));
    }

    function deployShutdown(address gov, address pit, uint256 min) public auth {
        require(address(cat) != address(0), "Missing previous step");

        // Deploy
        end = endFab.newEnd();

        // Internal references set up
        end.file("vat", address(vat));
        end.file("cat", address(cat));
        end.file("vow", address(vow));
        end.file("pot", address(pot));
        end.file("spot", address(spotter));

        // Internal auth
        vat.rely(address(end));
        cat.rely(address(end));
        vow.rely(address(end));
        pot.rely(address(end));
        spotter.rely(address(end));

        // Deploy ESM
        esm = esmFab.newESM(gov, address(end), address(pit), min);
        end.rely(address(esm));
    }

    function deployPause(uint delay, DSAuthority authority) public auth {
        require(address(dai) != address(0), "Missing previous step");
        require(address(end) != address(0), "Missing previous step");

        pause = pauseFab.newPause(delay, address(0), authority);

        vat.rely(address(pause.proxy()));
        cat.rely(address(pause.proxy()));
        vow.rely(address(pause.proxy()));
        jug.rely(address(pause.proxy()));
        pot.rely(address(pause.proxy()));
        spotter.rely(address(pause.proxy()));
        flap.rely(address(pause.proxy()));
        flop.rely(address(pause.proxy()));
        end.rely(address(pause.proxy()));
    }

    function deployCollateral(bytes32 ilk, address join, address pip) public auth {
        require(ilk != bytes32(""), "Missing ilk name");
        require(join != address(0), "Missing join address");
        require(pip != address(0), "Missing pip address");
        require(address(pause) != address(0), "Missing previous step");

        // Deploy
        ilks[ilk].flip = flipFab.newFlip(address(vat), ilk);
        ilks[ilk].join = join;
        Spotter(spotter).file(ilk, "pip", address(pip)); // Set pip

        // Internal references set up
        cat.file(ilk, "flip", address(ilks[ilk].flip));
        vat.init(ilk);
        jug.init(ilk);

        // Internal auth
        vat.rely(join);
        ilks[ilk].flip.rely(address(cat));
        ilks[ilk].flip.rely(address(end));
        ilks[ilk].flip.rely(address(pause.proxy()));
    }

    function releaseAuth() public auth {
        vat.deny(address(this));
        cat.deny(address(this));
        vow.deny(address(this));
        jug.deny(address(this));
        pot.deny(address(this));
        dai.deny(address(this));
        spotter.deny(address(this));
        flap.deny(address(this));
        flop.deny(address(this));
        end.deny(address(this));
    }

    function releaseAuthFlip(bytes32 ilk) public auth {
        ilks[ilk].flip.deny(address(this));
    }
}

contract Kicker {
    function kick(address urn, address gal, uint tab, uint lot, uint bid)
        public returns (uint);
}

contract VatLikeCat {
    function ilks(bytes32) external view returns (
        uint256 Art,   // wad
        uint256 rate,  // ray
        uint256 spot   // ray
    );
    function urns(bytes32,address) external view returns (
        uint256 ink,   // wad
        uint256 art    // wad
    );
    function grab(bytes32,address,address,address,int,int) external;
    function hope(address) external;
    function nope(address) external;
}

contract VowLike {
    function fess(uint) external;
}

contract VatLikeEnd {
    function dai(address) external view returns (uint256);
    function ilks(bytes32 ilk) external returns (
        uint256 Art,
        uint256 rate,
        uint256 spot,
        uint256 line,
        uint256 dust
    );
    function urns(bytes32 ilk, address urn) external returns (
        uint256 ink,
        uint256 art
    );
    function debt() external returns (uint256);
    function move(address src, address dst, uint256 rad) external;
    function hope(address) external;
    function flux(bytes32 ilk, address src, address dst, uint256 rad) external;
    function grab(bytes32 i, address u, address v, address w, int256 dink, int256 dart) external;
    function suck(address u, address v, uint256 rad) external;
    function cage() external;
}

contract CatLike {
    function ilks(bytes32) external returns (
        address flip,  // Liquidator
        uint256 chop,  // Liquidation Penalty   [ray]
        uint256 lump   // Liquidation Quantity  [rad]
    );
    function cage() external;
}

contract PotLike {
    function cage() external;
}

contract VowLikeEnd {
    function cage() external;
}

contract Flippy {
    function bids(uint id) external view returns (
        uint256 bid,
        uint256 lot,
        address guy,
        uint48  tic,
        uint48  end,
        address usr,
        address gal,
        uint256 tab
    );
    function yank(uint id) external;
}

contract PipLike {
    function read() external view returns (bytes32);
}

contract Spotty {
    function par() external view returns (uint256);
    function ilks(bytes32) external view returns (
        PipLike pip,
        uint256 mat
    );
    function cage() external;
}

contract VatLikeFlap {
    function move(address,address,uint) external;
}

contract GemLikeFlap {
    function move(address,address,uint) external;
    function burn(address,uint) external;
}

contract VatLikeFlip {
    function move(address,address,uint) external;
    function flux(bytes32,address,address,uint) external;
}

contract VatLikeFlop {
    function move(address,address,uint) external;
}

contract GemLikeFlop {
    function mint(address,uint) external;
}

contract GemLike {
    function decimals() public view returns (uint);
    function transfer(address,uint) external returns (bool);
    function transferFrom(address,address,uint) external returns (bool);
}

contract DSTokenLike {
    function mint(address,uint) external;
    function burn(address,uint) external;
}

contract VatLikeJoin {
    function slip(bytes32,address,int) external;
    function move(address,address,uint) external;
}

contract VatLikeJug {
    function ilks(bytes32) external returns (
        uint256 Art,   // wad
        uint256 rate   // ray
    );
    function fold(bytes32,address,int) external;
}

contract LibNote {
    event LogNote(
        bytes4   indexed  sig,
        address  indexed  usr,
        bytes32  indexed  arg1,
        bytes32  indexed  arg2,
        bytes             data
    ) anonymous;

    modifier note {
        _;
        assembly {
            // log an 'anonymous' event with a constant 6 words of calldata
            // and four indexed topics: selector, caller, arg1 and arg2
            let mark := msize                         // end of memory ensures zero
            mstore(0x40, add(mark, 288))              // update free memory pointer
            mstore(mark, 0x20)                        // bytes type data offset
            mstore(add(mark, 0x20), 224)              // bytes size (padded)
            calldatacopy(add(mark, 0x40), 0, 224)     // bytes payload
            log4(mark, 288,                           // calldata
                 shl(224, shr(224, calldataload(0))), // msg.sig
                 caller,                              // msg.sender
                 calldataload(4),                     // arg1
                 calldataload(36)                     // arg2
                )
        }
    }
}

contract Cat is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { wards[usr] = 1; }
    function deny(address usr) external note auth { wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Cat/not-authorized");
        _;
    }

    // --- Data ---
    struct Ilk {
        address flip;  // Liquidator
        uint256 chop;  // Liquidation Penalty   [ray]
        uint256 lump;  // Liquidation Quantity  [wad]
    }

    mapping (bytes32 => Ilk) public ilks;

    uint256 public live;
    VatLikeCat public vat;
    VowLike public vow;

    // --- Events ---
    event Bite(
      bytes32 indexed ilk,
      address indexed urn,
      uint256 ink,
      uint256 art,
      uint256 tab,
      address flip,
      uint256 id
    );

    // --- Init ---
    constructor(address vat_) public {
        wards[msg.sender] = 1;
        vat = VatLikeCat(vat_);
        live = 1;
    }

    // --- Math ---
    uint constant ONE = 10 ** 27;

    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x);
    }
    function rmul(uint x, uint y) internal pure returns (uint z) {
        z = mul(x, y) / ONE;
    }
    function min(uint x, uint y) internal pure returns (uint z) {
        if (x > y) { z = y; } else { z = x; }
    }

    // --- Administration ---
    function file(bytes32 what, address data) external note auth {
        if (what == "vow") vow = VowLike(data);
        else revert("Cat/file-unrecognized-param");
    }
    function file(bytes32 ilk, bytes32 what, uint data) external note auth {
        if (what == "chop") ilks[ilk].chop = data;
        else if (what == "lump") ilks[ilk].lump = data;
        else revert("Cat/file-unrecognized-param");
    }
    function file(bytes32 ilk, bytes32 what, address flip) external note auth {
        if (what == "flip") {
            vat.nope(ilks[ilk].flip);
            ilks[ilk].flip = flip;
            vat.hope(flip);
        }
        else revert("Cat/file-unrecognized-param");
    }

    // --- CDP Liquidation ---
    function bite(bytes32 ilk, address urn) external returns (uint id) {
        (, uint rate, uint spot) = vat.ilks(ilk);
        (uint ink, uint art) = vat.urns(ilk, urn);

        require(live == 1, "Cat/not-live");
        require(spot > 0 && mul(ink, spot) < mul(art, rate), "Cat/not-unsafe");

        uint lot = min(ink, ilks[ilk].lump);
        art      = min(art, mul(lot, art) / ink);

        require(lot <= 2**255 && art <= 2**255, "Cat/overflow");
        vat.grab(ilk, urn, address(this), address(vow), -int(lot), -int(art));

        vow.fess(mul(art, rate));
        id = Kicker(ilks[ilk].flip).kick({ urn: urn
                                         , gal: address(vow)
                                         , tab: rmul(mul(art, rate), ilks[ilk].chop)
                                         , lot: lot
                                         , bid: 0
                                         });

        emit Bite(ilk, urn, lot, art, mul(art, rate), ilks[ilk].flip, id);
    }

    function cage() external note auth {
        live = 0;
    }
}

contract Dai is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address guy) external note auth { wards[guy] = 1; }
    function deny(address guy) external note auth { wards[guy] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Dai/not-authorized");
        _;
    }

    // --- ERC20 Data ---
    string  public constant name     = "Dai Stablecoin";
    string  public constant symbol   = "DAI";
    string  public constant version  = "1";
    uint8   public constant decimals = 18;
    uint256 public totalSupply;

    mapping (address => uint)                      public balanceOf;
    mapping (address => mapping (address => uint)) public allowance;
    mapping (address => uint)                      public nonces;

    event Approval(address indexed src, address indexed guy, uint wad);
    event Transfer(address indexed src, address indexed dst, uint wad);

    // --- Math ---
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x);
    }
    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x);
    }

    // --- EIP712 niceties ---
    bytes32 public DOMAIN_SEPARATOR;
    // bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)");
    bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;

    constructor(uint256 chainId_) public {
        wards[msg.sender] = 1;
        DOMAIN_SEPARATOR = keccak256(abi.encode(
            keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
            keccak256(bytes(name)),
            keccak256(bytes(version)),
            chainId_,
            address(this)
        ));
    }

    // --- Token ---
    function transfer(address dst, uint wad) external returns (bool) {
        return transferFrom(msg.sender, dst, wad);
    }
    function transferFrom(address src, address dst, uint wad)
        public returns (bool)
    {
        require(balanceOf[src] >= wad, "Dai/insufficient-balance");
        if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
            require(allowance[src][msg.sender] >= wad, "Dai/insufficient-allowance");
            allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
        }
        balanceOf[src] = sub(balanceOf[src], wad);
        balanceOf[dst] = add(balanceOf[dst], wad);
        emit Transfer(src, dst, wad);
        return true;
    }
    function mint(address usr, uint wad) external auth {
        balanceOf[usr] = add(balanceOf[usr], wad);
        totalSupply    = add(totalSupply, wad);
        emit Transfer(address(0), usr, wad);
    }
    function burn(address usr, uint wad) external {
        require(balanceOf[usr] >= wad, "Dai/insufficient-balance");
        if (usr != msg.sender && allowance[usr][msg.sender] != uint(-1)) {
            require(allowance[usr][msg.sender] >= wad, "Dai/insufficient-allowance");
            allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad);
        }
        balanceOf[usr] = sub(balanceOf[usr], wad);
        totalSupply    = sub(totalSupply, wad);
        emit Transfer(usr, address(0), wad);
    }
    function approve(address usr, uint wad) external returns (bool) {
        allowance[msg.sender][usr] = wad;
        emit Approval(msg.sender, usr, wad);
        return true;
    }

    // --- Alias ---
    function push(address usr, uint wad) external {
        transferFrom(msg.sender, usr, wad);
    }
    function pull(address usr, uint wad) external {
        transferFrom(usr, msg.sender, wad);
    }
    function move(address src, address dst, uint wad) external {
        transferFrom(src, dst, wad);
    }

    // --- Approve by signature ---
    function permit(address holder, address spender, uint256 nonce, uint256 expiry,
                    bool allowed, uint8 v, bytes32 r, bytes32 s) external
    {
        bytes32 digest =
            keccak256(abi.encodePacked(
                "\x19\x01",
                DOMAIN_SEPARATOR,
                keccak256(abi.encode(PERMIT_TYPEHASH,
                                     holder,
                                     spender,
                                     nonce,
                                     expiry,
                                     allowed))
        ));

        require(holder != address(0), "Dai/invalid-address-0");
        require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit");
        require(expiry == 0 || now <= expiry, "Dai/permit-expired");
        require(nonce == nonces[holder]++, "Dai/invalid-nonce");
        uint wad = allowed ? uint(-1) : 0;
        allowance[holder][spender] = wad;
        emit Approval(holder, spender, wad);
    }
}

contract End is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address guy) external note auth { wards[guy] = 1; }
    function deny(address guy) external note auth { wards[guy] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "End/not-authorized");
        _;
    }

    // --- Data ---
    VatLikeEnd  public vat;
    CatLike  public cat;
    VowLikeEnd  public vow;
    PotLike  public pot;
    Spotty   public spot;

    uint256  public live;  // cage flag
    uint256  public when;  // time of cage
    uint256  public wait;  // processing cooldown length
    uint256  public debt;  // total outstanding dai following processing [rad]

    mapping (bytes32 => uint256) public tag;  // cage price           [ray]
    mapping (bytes32 => uint256) public gap;  // collateral shortfall [wad]
    mapping (bytes32 => uint256) public Art;  // total debt per ilk   [wad]
    mapping (bytes32 => uint256) public fix;  // final cash price     [ray]

    mapping (address => uint256)                      public bag;  // [wad]
    mapping (bytes32 => mapping (address => uint256)) public out;  // [wad]

    // --- Init ---
    constructor() public {
        wards[msg.sender] = 1;
        live = 1;
    }

    // --- Math ---
    function add(uint x, uint y) internal pure returns (uint z) {
        z = x + y;
        require(z >= 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;
    }
    uint constant WAD = 10 ** 18;
    uint constant RAY = 10 ** 27;
    function rmul(uint x, uint y) internal pure returns (uint z) {
        z = mul(x, y) / RAY;
    }
    function rdiv(uint x, uint y) internal pure returns (uint z) {
        z = mul(x, RAY) / y;
    }
    function wdiv(uint x, uint y) internal pure returns (uint z) {
        z = mul(x, WAD) / y;
    }

    // --- Administration ---
    function file(bytes32 what, address data) external note auth {
        require(live == 1, "End/not-live");
        if (what == "vat")  vat = VatLikeEnd(data);
        else if (what == "cat")  cat = CatLike(data);
        else if (what == "vow")  vow = VowLikeEnd(data);
        else if (what == "pot")  pot = PotLike(data);
        else if (what == "spot") spot = Spotty(data);
        else revert("End/file-unrecognized-param");
    }
    function file(bytes32 what, uint256 data) external note auth {
        require(live == 1, "End/not-live");
        if (what == "wait") wait = data;
        else revert("End/file-unrecognized-param");
    }

    // --- Settlement ---
    function cage() external note auth {
        require(live == 1, "End/not-live");
        live = 0;
        when = now;
        vat.cage();
        cat.cage();
        vow.cage();
        spot.cage();
        pot.cage();
    }

    function cage(bytes32 ilk) external note {
        require(live == 0, "End/still-live");
        require(tag[ilk] == 0, "End/tag-ilk-already-defined");
        (Art[ilk],,,,) = vat.ilks(ilk);
        (PipLike pip,) = spot.ilks(ilk);
        // par is a ray, pip returns a wad
        tag[ilk] = wdiv(spot.par(), uint(pip.read()));
    }

    function skip(bytes32 ilk, uint256 id) external note {
        require(tag[ilk] != 0, "End/tag-ilk-not-defined");

        (address flipV,,) = cat.ilks(ilk);
        Flippy flip = Flippy(flipV);
        (, uint rate,,,) = vat.ilks(ilk);
        (uint bid, uint lot,,,, address usr,, uint tab) = flip.bids(id);

        vat.suck(address(vow), address(vow),  tab);
        vat.suck(address(vow), address(this), bid);
        vat.hope(address(flip));
        flip.yank(id);

        uint art = tab / rate;
        Art[ilk] = add(Art[ilk], art);
        require(int(lot) >= 0 && int(art) >= 0, "End/overflow");
        vat.grab(ilk, usr, address(this), address(vow), int(lot), int(art));
    }

    function skim(bytes32 ilk, address urn) external note {
        require(tag[ilk] != 0, "End/tag-ilk-not-defined");
        (, uint rate,,,) = vat.ilks(ilk);
        (uint ink, uint art) = vat.urns(ilk, urn);

        uint owe = rmul(rmul(art, rate), tag[ilk]);
        uint wad = min(ink, owe);
        gap[ilk] = add(gap[ilk], sub(owe, wad));

        require(wad <= 2**255 && art <= 2**255, "End/overflow");
        vat.grab(ilk, urn, address(this), address(vow), -int(wad), -int(art));
    }

    function free(bytes32 ilk) external note {
        require(live == 0, "End/still-live");
        (uint ink, uint art) = vat.urns(ilk, msg.sender);
        require(art == 0, "End/art-not-zero");
        require(ink <= 2**255, "End/overflow");
        vat.grab(ilk, msg.sender, msg.sender, address(vow), -int(ink), 0);
    }

    function thaw() external note {
        require(live == 0, "End/still-live");
        require(debt == 0, "End/debt-not-zero");
        require(vat.dai(address(vow)) == 0, "End/surplus-not-zero");
        require(now >= add(when, wait), "End/wait-not-finished");
        debt = vat.debt();
    }
    function flow(bytes32 ilk) external note {
        require(debt != 0, "End/debt-zero");
        require(fix[ilk] == 0, "End/fix-ilk-already-defined");

        (, uint rate,,,) = vat.ilks(ilk);
        uint256 wad = rmul(rmul(Art[ilk], rate), tag[ilk]);
        fix[ilk] = rdiv(mul(sub(wad, gap[ilk]), RAY), debt);
    }

    function pack(uint256 wad) external note {
        require(debt != 0, "End/debt-zero");
        vat.move(msg.sender, address(vow), mul(wad, RAY));
        bag[msg.sender] = add(bag[msg.sender], wad);
    }
    function cash(bytes32 ilk, uint wad) external note {
        require(fix[ilk] != 0, "End/fix-ilk-not-defined");
        vat.flux(ilk, address(this), msg.sender, rmul(wad, fix[ilk]));
        out[ilk][msg.sender] = add(out[ilk][msg.sender], wad);
        require(out[ilk][msg.sender] <= bag[msg.sender], "End/insufficient-bag-balance");
    }
}

contract Flapper is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { wards[usr] = 1; }
    function deny(address usr) external note auth { wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Flapper/not-authorized");
        _;
    }

    // --- Data ---
    struct Bid {
        uint256 bid;
        uint256 lot;
        address guy;  // high bidder
        uint48  tic;  // expiry time
        uint48  end;
    }

    mapping (uint => Bid) public bids;

    VatLikeFlap  public   vat;
    GemLikeFlap  public   gem;

    uint256  constant ONE = 1.00E18;
    uint256  public   beg = 1.05E18;  // 5% minimum bid increase
    uint48   public   ttl = 3 hours;  // 3 hours bid duration
    uint48   public   tau = 2 days;   // 2 days total auction length
    uint256  public kicks = 0;
    uint256  public live;

    // --- Events ---
    event Kick(
      uint256 id,
      uint256 lot,
      uint256 bid
    );

    // --- Init ---
    constructor(address vat_, address gem_) public {
        wards[msg.sender] = 1;
        vat = VatLikeFlap(vat_);
        gem = GemLikeFlap(gem_);
        live = 1;
    }

    // --- Math ---
    function add(uint48 x, uint48 y) internal pure returns (uint48 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);
    }

    // --- Admin ---
    function file(bytes32 what, uint data) external note auth {
        if (what == "beg") beg = data;
        else if (what == "ttl") ttl = uint48(data);
        else if (what == "tau") tau = uint48(data);
        else revert("Flapper/file-unrecognized-param");
    }

    // --- Auction ---
    function kick(uint lot, uint bid) external auth returns (uint id) {
        require(live == 1, "Flapper/not-live");
        require(kicks < uint(-1), "Flapper/overflow");
        id = ++kicks;

        bids[id].bid = bid;
        bids[id].lot = lot;
        bids[id].guy = msg.sender; // configurable??
        bids[id].end = add(uint48(now), tau);

        vat.move(msg.sender, address(this), lot);

        emit Kick(id, lot, bid);
    }
    function tick(uint id) external note {
        require(bids[id].end < now, "Flapper/not-finished");
        require(bids[id].tic == 0, "Flapper/bid-already-placed");
        bids[id].end = add(uint48(now), tau);
    }
    function tend(uint id, uint lot, uint bid) external note {
        require(live == 1, "Flapper/not-live");
        require(bids[id].guy != address(0), "Flapper/guy-not-set");
        require(bids[id].tic > now || bids[id].tic == 0, "Flapper/already-finished-tic");
        require(bids[id].end > now, "Flapper/already-finished-end");

        require(lot == bids[id].lot, "Flapper/lot-not-matching");
        require(bid >  bids[id].bid, "Flapper/bid-not-higher");
        require(mul(bid, ONE) >= mul(beg, bids[id].bid), "Flapper/insufficient-increase");

        gem.move(msg.sender, bids[id].guy, bids[id].bid);
        gem.move(msg.sender, address(this), bid - bids[id].bid);

        bids[id].guy = msg.sender;
        bids[id].bid = bid;
        bids[id].tic = add(uint48(now), ttl);
    }
    function deal(uint id) external note {
        require(live == 1, "Flapper/not-live");
        require(bids[id].tic != 0 && (bids[id].tic < now || bids[id].end < now), "Flapper/not-finished");
        vat.move(address(this), bids[id].guy, bids[id].lot);
        gem.burn(address(this), bids[id].bid);
        delete bids[id];
    }

    function cage(uint rad) external note auth {
       live = 0;
       vat.move(address(this), msg.sender, rad);
    }
    function yank(uint id) external note {
        require(live == 0, "Flapper/still-live");
        require(bids[id].guy != address(0), "Flapper/guy-not-set");
        gem.move(address(this), bids[id].guy, bids[id].bid);
        delete bids[id];
    }
}

contract Flipper is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { wards[usr] = 1; }
    function deny(address usr) external note auth { wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Flipper/not-authorized");
        _;
    }

    // --- Data ---
    struct Bid {
        uint256 bid;
        uint256 lot;
        address guy;  // high bidder
        uint48  tic;  // expiry time
        uint48  end;
        address usr;
        address gal;
        uint256 tab;
    }

    mapping (uint => Bid) public bids;

    VatLikeFlip public   vat;
    bytes32 public   ilk;

    uint256 constant ONE = 1.00E18;
    uint256 public   beg = 1.05E18;  // 5% minimum bid increase
    uint48  public   ttl = 3 hours;  // 3 hours bid duration
    uint48  public   tau = 2 days;   // 2 days total auction length
    uint256 public kicks = 0;

    // --- Events ---
    event Kick(
      uint256 id,
      uint256 lot,
      uint256 bid,
      uint256 tab,
      address indexed usr,
      address indexed gal
    );

    // --- Init ---
    constructor(address vat_, bytes32 ilk_) public {
        vat = VatLikeFlip(vat_);
        ilk = ilk_;
        wards[msg.sender] = 1;
    }

    // --- Math ---
    function add(uint48 x, uint48 y) internal pure returns (uint48 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);
    }

    // --- Admin ---
    function file(bytes32 what, uint data) external note auth {
        if (what == "beg") beg = data;
        else if (what == "ttl") ttl = uint48(data);
        else if (what == "tau") tau = uint48(data);
        else revert("Flipper/file-unrecognized-param");
    }

    // --- Auction ---
    function kick(address usr, address gal, uint tab, uint lot, uint bid)
        public auth returns (uint id)
    {
        require(kicks < uint(-1), "Flipper/overflow");
        id = ++kicks;

        bids[id].bid = bid;
        bids[id].lot = lot;
        bids[id].guy = msg.sender; // configurable??
        bids[id].end = add(uint48(now), tau);
        bids[id].usr = usr;
        bids[id].gal = gal;
        bids[id].tab = tab;

        vat.flux(ilk, msg.sender, address(this), lot);

        emit Kick(id, lot, bid, tab, usr, gal);
    }
    function tick(uint id) external note {
        require(bids[id].end < now, "Flipper/not-finished");
        require(bids[id].tic == 0, "Flipper/bid-already-placed");
        bids[id].end = add(uint48(now), tau);
    }
    function tend(uint id, uint lot, uint bid) external note {
        require(bids[id].guy != address(0), "Flipper/guy-not-set");
        require(bids[id].tic > now || bids[id].tic == 0, "Flipper/already-finished-tic");
        require(bids[id].end > now, "Flipper/already-finished-end");

        require(lot == bids[id].lot, "Flipper/lot-not-matching");
        require(bid <= bids[id].tab, "Flipper/higher-than-tab");
        require(bid >  bids[id].bid, "Flipper/bid-not-higher");
        require(mul(bid, ONE) >= mul(beg, bids[id].bid) || bid == bids[id].tab, "Flipper/insufficient-increase");

        vat.move(msg.sender, bids[id].guy, bids[id].bid);
        vat.move(msg.sender, bids[id].gal, bid - bids[id].bid);

        bids[id].guy = msg.sender;
        bids[id].bid = bid;
        bids[id].tic = add(uint48(now), ttl);
    }
    function dent(uint id, uint lot, uint bid) external note {
        require(bids[id].guy != address(0), "Flipper/guy-not-set");
        require(bids[id].tic > now || bids[id].tic == 0, "Flipper/already-finished-tic");
        require(bids[id].end > now, "Flipper/already-finished-end");

        require(bid == bids[id].bid, "Flipper/not-matching-bid");
        require(bid == bids[id].tab, "Flipper/tend-not-finished");
        require(lot < bids[id].lot, "Flipper/lot-not-lower");
        require(mul(beg, lot) <= mul(bids[id].lot, ONE), "Flipper/insufficient-decrease");

        vat.move(msg.sender, bids[id].guy, bid);
        vat.flux(ilk, address(this), bids[id].usr, bids[id].lot - lot);

        bids[id].guy = msg.sender;
        bids[id].lot = lot;
        bids[id].tic = add(uint48(now), ttl);
    }
    function deal(uint id) external note {
        require(bids[id].tic != 0 && (bids[id].tic < now || bids[id].end < now), "Flipper/not-finished");
        vat.flux(ilk, address(this), bids[id].guy, bids[id].lot);
        delete bids[id];
    }

    function yank(uint id) external note auth {
        require(bids[id].guy != address(0), "Flipper/guy-not-set");
        require(bids[id].bid < bids[id].tab, "Flipper/already-dent-phase");
        vat.flux(ilk, address(this), msg.sender, bids[id].lot);
        vat.move(msg.sender, bids[id].guy, bids[id].bid);
        delete bids[id];
    }
}

contract Flopper is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { wards[usr] = 1; }
    function deny(address usr) external note auth { wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Flopper/not-authorized");
        _;
    }

    // --- Data ---
    struct Bid {
        uint256 bid;
        uint256 lot;
        address guy;  // high bidder
        uint48  tic;  // expiry time
        uint48  end;
    }

    mapping (uint => Bid) public bids;

    VatLikeFlop  public   vat;
    GemLikeFlop  public   gem;

    uint256  constant ONE = 1.00E18;
    uint256  public   beg = 1.05E18;  // 5% minimum bid increase
    uint256  public   pad = 1.50E18;  // 50% lot increase for tick
    uint48   public   ttl = 3 hours;  // 3 hours bid lifetime
    uint48   public   tau = 2 days;   // 2 days total auction length
    uint256  public kicks = 0;
    uint256  public live;

    // --- Events ---
    event Kick(
      uint256 id,
      uint256 lot,
      uint256 bid,
      address indexed gal
    );

    // --- Init ---
    constructor(address vat_, address gem_) public {
        wards[msg.sender] = 1;
        vat = VatLikeFlop(vat_);
        gem = GemLikeFlop(gem_);
        live = 1;
    }

    // --- Math ---
    function add(uint48 x, uint48 y) internal pure returns (uint48 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);
    }

    // --- Admin ---
    function file(bytes32 what, uint data) external note auth {
        if (what == "beg") beg = data;
        else if (what == "pad") pad = data;
        else if (what == "ttl") ttl = uint48(data);
        else if (what == "tau") tau = uint48(data);
        else revert("Flopper/file-unrecognized-param");
    }

    // --- Auction ---
    function kick(address gal, uint lot, uint bid) external auth returns (uint id) {
        require(live == 1, "Flopper/not-live");
        require(kicks < uint(-1), "Flopper/overflow");
        id = ++kicks;

        bids[id].bid = bid;
        bids[id].lot = lot;
        bids[id].guy = gal;
        bids[id].end = add(uint48(now), tau);

        emit Kick(id, lot, bid, gal);
    }
    function tick(uint id) external note {
        require(bids[id].end < now, "Flopper/not-finished");
        require(bids[id].tic == 0, "Flopper/bid-already-placed");
        bids[id].lot = mul(pad, bids[id].lot) / ONE;
        bids[id].end = add(uint48(now), tau);
    }
    function dent(uint id, uint lot, uint bid) external note {
        require(live == 1, "Flopper/not-live");
        require(bids[id].guy != address(0), "Flopper/guy-not-set");
        require(bids[id].tic > now || bids[id].tic == 0, "Flopper/already-finished-tic");
        require(bids[id].end > now, "Flopper/already-finished-end");

        require(bid == bids[id].bid, "Flopper/not-matching-bid");
        require(lot <  bids[id].lot, "Flopper/lot-not-lower");
        require(mul(beg, lot) <= mul(bids[id].lot, ONE), "Flopper/insufficient-decrease");

        vat.move(msg.sender, bids[id].guy, bid);

        bids[id].guy = msg.sender;
        bids[id].lot = lot;
        bids[id].tic = add(uint48(now), ttl);
    }
    function deal(uint id) external note {
        require(live == 1, "Flopper/not-live");
        require(bids[id].tic != 0 && (bids[id].tic < now || bids[id].end < now), "Flopper/not-finished");
        gem.mint(bids[id].guy, bids[id].lot);
        delete bids[id];
    }

    function cage() external note auth {
       live = 0;
    }
    function yank(uint id) external note {
        require(live == 0, "Flopper/still-live");
        require(bids[id].guy != address(0), "Flopper/guy-not-set");
        vat.move(address(this), bids[id].guy, bids[id].bid);
        delete bids[id];
    }
}

contract GemJoin is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { wards[usr] = 1; }
    function deny(address usr) external note auth { wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "GemJoin/not-authorized");
        _;
    }

    VatLikeJoin public vat;
    bytes32 public ilk;
    GemLike public gem;
    uint    public dec;
    uint    public live;  // Access Flag

    constructor(address vat_, bytes32 ilk_, address gem_) public {
        wards[msg.sender] = 1;
        live = 1;
        vat = VatLikeJoin(vat_);
        ilk = ilk_;
        gem = GemLike(gem_);
        dec = gem.decimals();
    }
    function cage() external note auth {
        live = 0;
    }
    function join(address usr, uint wad) external note {
        require(live == 1, "GemJoin/not-live");
        require(int(wad) >= 0, "GemJoin/overflow");
        vat.slip(ilk, usr, int(wad));
        require(gem.transferFrom(msg.sender, address(this), wad), "GemJoin/failed-transfer");
    }
    function exit(address usr, uint wad) external note {
        require(wad <= 2 ** 255, "GemJoin/overflow");
        vat.slip(ilk, msg.sender, -int(wad));
        require(gem.transfer(usr, wad), "GemJoin/failed-transfer");
    }
}

contract ETHJoin is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { wards[usr] = 1; }
    function deny(address usr) external note auth { wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "ETHJoin/not-authorized");
        _;
    }

    VatLikeJoin public vat;
    bytes32 public ilk;
    uint    public live;  // Access Flag

    constructor(address vat_, bytes32 ilk_) public {
        wards[msg.sender] = 1;
        live = 1;
        vat = VatLikeJoin(vat_);
        ilk = ilk_;
    }
    function cage() external note auth {
        live = 0;
    }
    function join(address usr) external payable note {
        require(live == 1, "ETHJoin/not-live");
        require(int(msg.value) >= 0, "ETHJoin/overflow");
        vat.slip(ilk, usr, int(msg.value));
    }
    function exit(address payable usr, uint wad) external note {
        require(int(wad) >= 0, "ETHJoin/overflow");
        vat.slip(ilk, msg.sender, -int(wad));
        usr.transfer(wad);
    }
}

contract DaiJoin is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { wards[usr] = 1; }
    function deny(address usr) external note auth { wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "DaiJoin/not-authorized");
        _;
    }

    VatLikeJoin public vat;
    DSTokenLike public dai;
    uint    public live;  // Access Flag

    constructor(address vat_, address dai_) public {
        wards[msg.sender] = 1;
        live = 1;
        vat = VatLikeJoin(vat_);
        dai = DSTokenLike(dai_);
    }
    function cage() external note auth {
        live = 0;
    }
    uint constant ONE = 10 ** 27;
    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x);
    }
    function join(address usr, uint wad) external note {
        vat.move(address(this), usr, mul(ONE, wad));
        dai.burn(msg.sender, wad);
    }
    function exit(address usr, uint wad) external note {
        require(live == 1, "DaiJoin/not-live");
        vat.move(msg.sender, address(this), mul(ONE, wad));
        dai.mint(usr, wad);
    }
}

contract Jug is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { wards[usr] = 1; }
    function deny(address usr) external note auth { wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Jug/not-authorized");
        _;
    }

    // --- Data ---
    struct Ilk {
        uint256 duty;
        uint256  rho;
    }

    mapping (bytes32 => Ilk) public ilks;
    VatLikeJug                  public vat;
    address                  public vow;
    uint256                  public base;

    // --- Init ---
    constructor(address vat_) public {
        wards[msg.sender] = 1;
        vat = VatLikeJug(vat_);
    }

    // --- Math ---
    function rpow(uint x, uint n, uint b) internal pure returns (uint z) {
      assembly {
        switch x case 0 {switch n case 0 {z := b} default {z := 0}}
        default {
          switch mod(n, 2) case 0 { z := b } default { z := x }
          let half := div(b, 2)  // for rounding.
          for { n := div(n, 2) } n { n := div(n,2) } {
            let xx := mul(x, x)
            if iszero(eq(div(xx, x), x)) { revert(0,0) }
            let xxRound := add(xx, half)
            if lt(xxRound, xx) { revert(0,0) }
            x := div(xxRound, b)
            if mod(n,2) {
              let zx := mul(z, x)
              if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
              let zxRound := add(zx, half)
              if lt(zxRound, zx) { revert(0,0) }
              z := div(zxRound, b)
            }
          }
        }
      }
    }
    uint256 constant ONE = 10 ** 27;
    function add(uint x, uint y) internal pure returns (uint z) {
        z = x + y;
        require(z >= x);
    }
    function diff(uint x, uint y) internal pure returns (int z) {
        z = int(x) - int(y);
        require(int(x) >= 0 && int(y) >= 0);
    }
    function rmul(uint x, uint y) internal pure returns (uint z) {
        z = x * y;
        require(y == 0 || z / y == x);
        z = z / ONE;
    }

    // --- Administration ---
    function init(bytes32 ilk) external note auth {
        Ilk storage i = ilks[ilk];
        require(i.duty == 0, "Jug/ilk-already-init");
        i.duty = ONE;
        i.rho  = now;
    }
    function file(bytes32 ilk, bytes32 what, uint data) external note auth {
        require(now == ilks[ilk].rho, "Jug/rho-not-updated");
        if (what == "duty") ilks[ilk].duty = data;
        else revert("Jug/file-unrecognized-param");
    }
    function file(bytes32 what, uint data) external note auth {
        if (what == "base") base = data;
        else revert("Jug/file-unrecognized-param");
    }
    function file(bytes32 what, address data) external note auth {
        if (what == "vow") vow = data;
        else revert("Jug/file-unrecognized-param");
    }

    // --- Stability Fee Collection ---
    function drip(bytes32 ilk) external note returns (uint rate) {
        require(now >= ilks[ilk].rho, "Jug/invalid-now");
        (, uint prev) = vat.ilks(ilk);
        rate = rmul(rpow(add(base, ilks[ilk].duty), now - ilks[ilk].rho, ONE), prev);
        vat.fold(ilk, vow, diff(rate, prev));
        ilks[ilk].rho = now;
    }
}

contract DSNote {
    event LogNote(
        bytes4   indexed  sig,
        address  indexed  guy,
        bytes32  indexed  foo,
        bytes32  indexed  bar,
        uint256           wad,
        bytes             fax
    ) anonymous;

    modifier note {
        bytes32 foo;
        bytes32 bar;
        uint256 wad;

        assembly {
            foo := calldataload(4)
            bar := calldataload(36)
            wad := callvalue
        }

        emit LogNote(msg.sig, msg.sender, foo, bar, wad, msg.data);

        _;
    }
}

contract DSPause is DSAuth, DSNote {

    // --- admin ---

    modifier wait { require(msg.sender == address(proxy), "ds-pause-undelayed-call"); _; }

    function setOwner(address owner_) public wait {
        owner = owner_;
        emit LogSetOwner(owner);
    }
    function setAuthority(DSAuthority authority_) public wait {
        authority = authority_;
        emit LogSetAuthority(address(authority));
    }
    function setDelay(uint delay_) public note wait {
        delay = delay_;
    }

    // --- math ---

    function add(uint x, uint y) internal pure returns (uint z) {
        z = x + y;
        require(z >= x, "ds-pause-addition-overflow");
    }

    // --- data ---

    mapping (bytes32 => bool) public plans;
    DSPauseProxy public proxy;
    uint         public delay;

    // --- init ---

    constructor(uint delay_, address owner_, DSAuthority authority_) public {
        delay = delay_;
        owner = owner_;
        authority = authority_;
        proxy = new DSPauseProxy();
    }

    // --- util ---

    function hash(address usr, bytes32 tag, bytes memory fax, uint eta)
        internal pure
        returns (bytes32)
    {
        return keccak256(abi.encode(usr, tag, fax, eta));
    }

    function soul(address usr)
        internal view
        returns (bytes32 tag)
    {
        assembly { tag := extcodehash(usr) }
    }

    // --- operations ---

    function plot(address usr, bytes32 tag, bytes memory fax, uint eta)
        public note auth
    {
        require(eta >= add(now, delay), "ds-pause-delay-not-respected");
        plans[hash(usr, tag, fax, eta)] = true;
    }

    function drop(address usr, bytes32 tag, bytes memory fax, uint eta)
        public note auth
    {
        plans[hash(usr, tag, fax, eta)] = false;
    }

    function exec(address usr, bytes32 tag, bytes memory fax, uint eta)
        public note
        returns (bytes memory out)
    {
        require(plans[hash(usr, tag, fax, eta)], "ds-pause-unplotted-plan");
        require(soul(usr) == tag,                "ds-pause-wrong-codehash");
        require(now >= eta,                      "ds-pause-premature-exec");

        plans[hash(usr, tag, fax, eta)] = false;

        out = proxy.exec(usr, fax);
        require(proxy.owner() == address(this), "ds-pause-illegal-storage-change");
    }
}

contract DSPauseProxy {
    address public owner;
    modifier auth { require(msg.sender == owner, "ds-pause-proxy-unauthorized"); _; }
    constructor() public { owner = msg.sender; }

    function exec(address usr, bytes memory fax)
        public auth
        returns (bytes memory out)
    {
        bool ok;
        (ok, out) = usr.delegatecall(fax);
        require(ok, "ds-pause-delegatecall-error");
    }
}

contract VatLikePot {
    function move(address,address,uint256) external;
    function suck(address,address,uint256) external;
}

contract Pot is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address guy) external note auth { wards[guy] = 1; }
    function deny(address guy) external note auth { wards[guy] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Pot/not-authorized");
        _;
    }

    // --- Data ---
    mapping (address => uint256) public pie;  // user Savings Dai

    uint256 public Pie;  // total Savings Dai
    uint256 public dsr;  // the Dai Savings Rate
    uint256 public chi;  // the Rate Accumulator

    VatLikePot public vat;  // CDP engine
    address public vow;  // debt engine
    uint256 public rho;  // time of last drip

    uint256 public live;  // Access Flag

    // --- Init ---
    constructor(address vat_) public {
        wards[msg.sender] = 1;
        vat = VatLikePot(vat_);
        dsr = ONE;
        chi = ONE;
        rho = now;
        live = 1;
    }

    // --- Math ---
    uint256 constant ONE = 10 ** 27;
    function rpow(uint x, uint n, uint base) internal pure returns (uint z) {
        assembly {
            switch x case 0 {switch n case 0 {z := base} default {z := 0}}
            default {
                switch mod(n, 2) case 0 { z := base } default { z := x }
                let half := div(base, 2)  // for rounding.
                for { n := div(n, 2) } n { n := div(n,2) } {
                    let xx := mul(x, x)
                    if iszero(eq(div(xx, x), x)) { revert(0,0) }
                    let xxRound := add(xx, half)
                    if lt(xxRound, xx) { revert(0,0) }
                    x := div(xxRound, base)
                    if mod(n,2) {
                        let zx := mul(z, x)
                        if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
                        let zxRound := add(zx, half)
                        if lt(zxRound, zx) { revert(0,0) }
                        z := div(zxRound, base)
                    }
                }
            }
        }
    }

    function rmul(uint x, uint y) internal pure returns (uint z) {
        z = mul(x, y) / ONE;
    }

    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x);
    }

    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x);
    }

    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x);
    }

    // --- Administration ---
    function file(bytes32 what, uint256 data) external note auth {
        require(live == 1, "Pot/not-live");
        require(now == rho, "Pot/rho-not-updated");
        if (what == "dsr") dsr = data;
        else revert("Pot/file-unrecognized-param");
    }

    function file(bytes32 what, address addr) external note auth {
        if (what == "vow") vow = addr;
        else revert("Pot/file-unrecognized-param");
    }

    function cage() external note auth {
        live = 0;
        dsr = ONE;
    }

    // --- Savings Rate Accumulation ---
    function drip() external note returns (uint tmp) {
        require(now >= rho, "Pot/invalid-now");
        tmp = rmul(rpow(dsr, now - rho, ONE), chi);
        uint chi_ = sub(tmp, chi);
        chi = tmp;
        rho = now;
        vat.suck(address(vow), address(this), mul(Pie, chi_));
    }

    // --- Savings Dai Management ---
    function join(uint wad) external note {
        require(now == rho, "Pot/rho-not-updated");
        pie[msg.sender] = add(pie[msg.sender], wad);
        Pie             = add(Pie,             wad);
        vat.move(msg.sender, address(this), mul(chi, wad));
    }

    function exit(uint wad) external note {
        pie[msg.sender] = sub(pie[msg.sender], wad);
        Pie             = sub(Pie,             wad);
        vat.move(address(this), msg.sender, mul(chi, wad));
    }
}

contract VatLikeSpot {
    function file(bytes32, bytes32, uint) external;
}

contract PipLikeSpot {
    function peek() external returns (bytes32, bool);
}

contract Spotter is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address guy) external note auth { wards[guy] = 1;  }
    function deny(address guy) external note auth { wards[guy] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Spotter/not-authorized");
        _;
    }

    // --- Data ---
    struct Ilk {
        PipLikeSpot pip;
        uint256 mat;
    }

    mapping (bytes32 => Ilk) public ilks;

    VatLikeSpot public vat;
    uint256 public par; // ref per dai

    uint256 public live;

    // --- Events ---
    event Poke(
      bytes32 ilk,
      bytes32 val,
      uint256 spot
    );

    // --- Init ---
    constructor(address vat_) public {
        wards[msg.sender] = 1;
        vat = VatLikeSpot(vat_);
        par = ONE;
        live = 1;
    }

    // --- Math ---
    uint constant ONE = 10 ** 27;

    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x);
    }
    function rdiv(uint x, uint y) internal pure returns (uint z) {
        z = mul(x, ONE) / y;
    }

    // --- Administration ---
    function file(bytes32 ilk, bytes32 what, address pip_) external note auth {
        require(live == 1, "Spotter/not-live");
        if (what == "pip") ilks[ilk].pip = PipLikeSpot(pip_);
        else revert("Spotter/file-unrecognized-param");
    }
    function file(bytes32 what, uint data) external note auth {
        require(live == 1, "Spotter/not-live");
        if (what == "par") par = data;
        else revert("Spotter/file-unrecognized-param");
    }
    function file(bytes32 ilk, bytes32 what, uint data) external note auth {
        require(live == 1, "Spotter/not-live");
        if (what == "mat") ilks[ilk].mat = data;
        else revert("Spotter/file-unrecognized-param");
    }

    // --- Update value ---
    function poke(bytes32 ilk) external {
        (bytes32 val, bool has) = ilks[ilk].pip.peek();
        uint256 spot = has ? rdiv(rdiv(mul(uint(val), 10 ** 9), par), ilks[ilk].mat) : 0;
        vat.file(ilk, "spot", spot);
        emit Poke(ilk, val, spot);
    }

    function cage() external note auth {
        live = 0;
    }
}

contract Vat {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { require(live == 1, "Vat/not-live"); wards[usr] = 1; }
    function deny(address usr) external note auth { require(live == 1, "Vat/not-live"); wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Vat/not-authorized");
        _;
    }

    mapping(address => mapping (address => uint)) public can;
    function hope(address usr) external note { can[msg.sender][usr] = 1; }
    function nope(address usr) external note { can[msg.sender][usr] = 0; }
    function wish(address bit, address usr) internal view returns (bool) {
        return either(bit == usr, can[bit][usr] == 1);
    }

    // --- Data ---
    struct Ilk {
        uint256 Art;   // Total Normalised Debt     [wad]
        uint256 rate;  // Accumulated Rates         [ray]
        uint256 spot;  // Price with Safety Margin  [ray]
        uint256 line;  // Debt Ceiling              [rad]
        uint256 dust;  // Urn Debt Floor            [rad]
    }
    struct Urn {
        uint256 ink;   // Locked Collateral  [wad]
        uint256 art;   // Normalised Debt    [wad]
    }

    mapping (bytes32 => Ilk)                       public ilks;
    mapping (bytes32 => mapping (address => Urn )) public urns;
    mapping (bytes32 => mapping (address => uint)) public gem;  // [wad]
    mapping (address => uint256)                   public dai;  // [rad]
    mapping (address => uint256)                   public sin;  // [rad]

    uint256 public debt;  // Total Dai Issued    [rad]
    uint256 public vice;  // Total Unbacked Dai  [rad]
    uint256 public Line;  // Total Debt Ceiling  [rad]
    uint256 public live;  // Access Flag

    // --- Logs ---
    event LogNote(
        bytes4   indexed  sig,
        bytes32  indexed  arg1,
        bytes32  indexed  arg2,
        bytes32  indexed  arg3,
        bytes             data
    ) anonymous;

    modifier note {
        _;
        assembly {
            // log an 'anonymous' event with a constant 6 words of calldata
            // and four indexed topics: the selector and the first three args
            let mark := msize                         // end of memory ensures zero
            mstore(0x40, add(mark, 288))              // update free memory pointer
            mstore(mark, 0x20)                        // bytes type data offset
            mstore(add(mark, 0x20), 224)              // bytes size (padded)
            calldatacopy(add(mark, 0x40), 0, 224)     // bytes payload
            log4(mark, 288,                           // calldata
                 shl(224, shr(224, calldataload(0))), // msg.sig
                 calldataload(4),                     // arg1
                 calldataload(36),                    // arg2
                 calldataload(68)                     // arg3
                )
        }
    }

    // --- Init ---
    constructor() public {
        wards[msg.sender] = 1;
        live = 1;
    }

    // --- Math ---
    function add(uint x, int y) internal pure returns (uint z) {
        z = x + uint(y);
        require(y >= 0 || z <= x);
        require(y <= 0 || z >= x);
    }
    function sub(uint x, int y) internal pure returns (uint z) {
        z = x - uint(y);
        require(y <= 0 || z <= x);
        require(y >= 0 || z >= x);
    }
    function mul(uint x, int y) internal pure returns (int z) {
        z = int(x) * y;
        require(int(x) >= 0);
        require(y == 0 || z / y == int(x));
    }
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x);
    }
    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x);
    }
    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x);
    }

    // --- Administration ---
    function init(bytes32 ilk) external note auth {
        require(ilks[ilk].rate == 0, "Vat/ilk-already-init");
        ilks[ilk].rate = 10 ** 27;
    }
    function file(bytes32 what, uint data) external note auth {
        require(live == 1, "Vat/not-live");
        if (what == "Line") Line = data;
        else revert("Vat/file-unrecognized-param");
    }
    function file(bytes32 ilk, bytes32 what, uint data) external note auth {
        require(live == 1, "Vat/not-live");
        if (what == "spot") ilks[ilk].spot = data;
        else if (what == "line") ilks[ilk].line = data;
        else if (what == "dust") ilks[ilk].dust = data;
        else revert("Vat/file-unrecognized-param");
    }
    function cage() external note auth {
        live = 0;
    }

    // --- Fungibility ---
    function slip(bytes32 ilk, address usr, int256 wad) external note auth {
        gem[ilk][usr] = add(gem[ilk][usr], wad);
    }
    function flux(bytes32 ilk, address src, address dst, uint256 wad) external note {
        require(wish(src, msg.sender), "Vat/not-allowed");
        gem[ilk][src] = sub(gem[ilk][src], wad);
        gem[ilk][dst] = add(gem[ilk][dst], wad);
    }
    function move(address src, address dst, uint256 rad) external note {
        require(wish(src, msg.sender), "Vat/not-allowed");
        dai[src] = sub(dai[src], rad);
        dai[dst] = add(dai[dst], rad);
    }

    function either(bool x, bool y) internal pure returns (bool z) {
        assembly{ z := or(x, y)}
    }
    function both(bool x, bool y) internal pure returns (bool z) {
        assembly{ z := and(x, y)}
    }

    // --- CDP Manipulation ---
    function frob(bytes32 i, address u, address v, address w, int dink, int dart) external note {
        // system is live
        require(live == 1, "Vat/not-live");

        Urn memory urn = urns[i][u];
        Ilk memory ilk = ilks[i];
        // ilk has been initialised
        require(ilk.rate != 0, "Vat/ilk-not-init");

        urn.ink = add(urn.ink, dink);
        urn.art = add(urn.art, dart);
        ilk.Art = add(ilk.Art, dart);

        int dtab = mul(ilk.rate, dart);
        uint tab = mul(ilk.rate, urn.art);
        debt     = add(debt, dtab);

        // either debt has decreased, or debt ceilings are not exceeded
        require(either(dart <= 0, both(mul(ilk.Art, ilk.rate) <= ilk.line, debt <= Line)), "Vat/ceiling-exceeded");
        // urn is either less risky than before, or it is safe
        require(either(both(dart <= 0, dink >= 0), tab <= mul(urn.ink, ilk.spot)), "Vat/not-safe");

        // urn is either more safe, or the owner consents
        require(either(both(dart <= 0, dink >= 0), wish(u, msg.sender)), "Vat/not-allowed-u");
        // collateral src consents
        require(either(dink <= 0, wish(v, msg.sender)), "Vat/not-allowed-v");
        // debt dst consents
        require(either(dart >= 0, wish(w, msg.sender)), "Vat/not-allowed-w");

        // urn has no debt, or a non-dusty amount
        require(either(urn.art == 0, tab >= ilk.dust), "Vat/dust");

        gem[i][v] = sub(gem[i][v], dink);
        dai[w]    = add(dai[w],    dtab);

        urns[i][u] = urn;
        ilks[i]    = ilk;
    }
    // --- CDP Fungibility ---
    function fork(bytes32 ilk, address src, address dst, int dink, int dart) external note {
        Urn storage u = urns[ilk][src];
        Urn storage v = urns[ilk][dst];
        Ilk storage i = ilks[ilk];

        u.ink = sub(u.ink, dink);
        u.art = sub(u.art, dart);
        v.ink = add(v.ink, dink);
        v.art = add(v.art, dart);

        uint utab = mul(u.art, i.rate);
        uint vtab = mul(v.art, i.rate);

        // both sides consent
        require(both(wish(src, msg.sender), wish(dst, msg.sender)), "Vat/not-allowed");

        // both sides safe
        require(utab <= mul(u.ink, i.spot), "Vat/not-safe-src");
        require(vtab <= mul(v.ink, i.spot), "Vat/not-safe-dst");

        // both sides non-dusty
        require(either(utab >= i.dust, u.art == 0), "Vat/dust-src");
        require(either(vtab >= i.dust, v.art == 0), "Vat/dust-dst");
    }
    // --- CDP Confiscation ---
    function grab(bytes32 i, address u, address v, address w, int dink, int dart) external note auth {
        Urn storage urn = urns[i][u];
        Ilk storage ilk = ilks[i];

        urn.ink = add(urn.ink, dink);
        urn.art = add(urn.art, dart);
        ilk.Art = add(ilk.Art, dart);

        int dtab = mul(ilk.rate, dart);

        gem[i][v] = sub(gem[i][v], dink);
        sin[w]    = sub(sin[w],    dtab);
        vice      = sub(vice,      dtab);
    }

    // --- Settlement ---
    function heal(uint rad) external note {
        address u = msg.sender;
        sin[u] = sub(sin[u], rad);
        dai[u] = sub(dai[u], rad);
        vice   = sub(vice,   rad);
        debt   = sub(debt,   rad);
    }
    function suck(address u, address v, uint rad) external note auth {
        sin[u] = add(sin[u], rad);
        dai[v] = add(dai[v], rad);
        vice   = add(vice,   rad);
        debt   = add(debt,   rad);
    }

    // --- Rates ---
    function fold(bytes32 i, address u, int rate) external note auth {
        require(live == 1, "Vat/not-live");
        Ilk storage ilk = ilks[i];
        ilk.rate = add(ilk.rate, rate);
        int rad  = mul(ilk.Art, rate);
        dai[u]   = add(dai[u], rad);
        debt     = add(debt,   rad);
    }
}

contract FlopLike {
    function kick(address gal, uint lot, uint bid) external returns (uint);
    function cage() external;
    function live() external returns (uint);
}

contract FlapLike {
    function kick(uint lot, uint bid) external returns (uint);
    function cage(uint) external;
    function live() external returns (uint);
}

contract VatLikeVow {
    function dai (address) external view returns (uint);
    function sin (address) external view returns (uint);
    function heal(uint256) external;
    function hope(address) external;
    function nope(address) external;
}

contract Vow is LibNote {
    // --- Auth ---
    mapping (address => uint) public wards;
    function rely(address usr) external note auth { require(live == 1, "Vow/not-live"); wards[usr] = 1; }
    function deny(address usr) external note auth { wards[usr] = 0; }
    modifier auth {
        require(wards[msg.sender] == 1, "Vow/not-authorized");
        _;
    }

    // --- Data ---
    VatLikeVow public vat;
    FlapLike public flapper;
    FlopLike public flopper;

    mapping (uint256 => uint256) public sin; // debt queue
    uint256 public Sin;   // queued debt          [rad]
    uint256 public Ash;   // on-auction debt      [rad]

    uint256 public wait;  // flop delay
    uint256 public dump;  // flop initial lot size  [wad]
    uint256 public sump;  // flop fixed bid size    [rad]

    uint256 public bump;  // flap fixed lot size    [rad]
    uint256 public hump;  // surplus buffer       [rad]

    uint256 public live;

    // --- Init ---
    constructor(address vat_, address flapper_, address flopper_) public {
        wards[msg.sender] = 1;
        vat     = VatLikeVow(vat_);
        flapper = FlapLike(flapper_);
        flopper = FlopLike(flopper_);
        vat.hope(flapper_);
        live = 1;
    }

    // --- Math ---
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x);
    }
    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x);
    }
    function min(uint x, uint y) internal pure returns (uint z) {
        return x <= y ? x : y;
    }

    // --- Administration ---
    function file(bytes32 what, uint data) external note auth {
        if (what == "wait") wait = data;
        else if (what == "bump") bump = data;
        else if (what == "sump") sump = data;
        else if (what == "dump") dump = data;
        else if (what == "hump") hump = data;
        else revert("Vow/file-unrecognized-param");
    }

    function file(bytes32 what, address data) external note auth {
        if (what == "flapper") {
            vat.nope(address(flapper));
            flapper = FlapLike(data);
            vat.hope(data);
        }
        else if (what == "flopper") flopper = FlopLike(data);
        else revert("Vow/file-unrecognized-param");
    }

    // Push to debt-queue
    function fess(uint tab) external note auth {
        sin[now] = add(sin[now], tab);
        Sin = add(Sin, tab);
    }
    // Pop from debt-queue
    function flog(uint era) external note {
        require(add(era, wait) <= now, "Vow/wait-not-finished");
        Sin = sub(Sin, sin[era]);
        sin[era] = 0;
    }

    // Debt settlement
    function heal(uint rad) external note {
        require(rad <= vat.dai(address(this)), "Vow/insufficient-surplus");
        require(rad <= sub(sub(vat.sin(address(this)), Sin), Ash), "Vow/insufficient-debt");
        vat.heal(rad);
    }
    function kiss(uint rad) external note {
        require(rad <= Ash, "Vow/not-enough-ash");
        require(rad <= vat.dai(address(this)), "Vow/insufficient-surplus");
        Ash = sub(Ash, rad);
        vat.heal(rad);
    }

    // Debt auction
    function flop() external note returns (uint id) {
        require(sump <= sub(sub(vat.sin(address(this)), Sin), Ash), "Vow/insufficient-debt");
        require(vat.dai(address(this)) == 0, "Vow/surplus-not-zero");
        Ash = add(Ash, sump);
        id = flopper.kick(address(this), dump, sump);
    }
    // Surplus auction
    function flap() external note returns (uint id) {
        require(vat.dai(address(this)) >= add(add(vat.sin(address(this)), bump), hump), "Vow/insufficient-surplus");
        require(sub(sub(vat.sin(address(this)), Sin), Ash) == 0, "Vow/debt-not-zero");
        id = flapper.kick(bump, 0);
    }

    function cage() external note auth {
        require(live == 1, "Vow/not-live");
        live = 0;
        Sin = 0;
        Ash = 0;
        flapper.cage(vat.dai(address(flapper)));
        flopper.cage();
        vat.heal(min(vat.dai(address(this)), vat.sin(address(this))));
    }
}
        

Compiler Settings

{"remappings":[],"optimizer":{"runs":200,"enabled":true},"libraries":{},"evmVersion":"petersburg","compilationTarget":{"DssDeploy.sol":"DssDeploy"}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","payable":false,"inputs":[{"type":"address","name":"vatFab_","internalType":"contract VatFab"},{"type":"address","name":"jugFab_","internalType":"contract JugFab"},{"type":"address","name":"vowFab_","internalType":"contract VowFab"},{"type":"address","name":"catFab_","internalType":"contract CatFab"},{"type":"address","name":"daiFab_","internalType":"contract DaiFab"},{"type":"address","name":"daiJoinFab_","internalType":"contract DaiJoinFab"},{"type":"address","name":"flapFab_","internalType":"contract FlapFab"},{"type":"address","name":"flopFab_","internalType":"contract FlopFab"},{"type":"address","name":"flipFab_","internalType":"contract FlipFab"},{"type":"address","name":"spotFab_","internalType":"contract SpotFab"},{"type":"address","name":"potFab_","internalType":"contract PotFab"},{"type":"address","name":"endFab_","internalType":"contract EndFab"},{"type":"address","name":"esmFab_","internalType":"contract ESMFab"},{"type":"address","name":"pauseFab_","internalType":"contract PauseFab"}]},{"type":"event","name":"LogSetAuthority","inputs":[{"type":"address","name":"authority","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"LogSetOwner","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract DSAuthority"}],"name":"authority","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract Cat"}],"name":"cat","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract CatFab"}],"name":"catFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract Dai"}],"name":"dai","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract DaiFab"}],"name":"daiFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract DaiJoin"}],"name":"daiJoin","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract DaiJoinFab"}],"name":"daiJoinFab","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deployAuctions","inputs":[{"type":"address","name":"gov","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deployCollateral","inputs":[{"type":"bytes32","name":"ilk","internalType":"bytes32"},{"type":"address","name":"join","internalType":"address"},{"type":"address","name":"pip","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deployDai","inputs":[{"type":"uint256","name":"chainId","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deployLiquidator","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deployPause","inputs":[{"type":"uint256","name":"delay","internalType":"uint256"},{"type":"address","name":"authority","internalType":"contract DSAuthority"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deployShutdown","inputs":[{"type":"address","name":"gov","internalType":"address"},{"type":"address","name":"pit","internalType":"address"},{"type":"uint256","name":"min","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deployTaxation","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deployVat","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract End"}],"name":"end","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract EndFab"}],"name":"endFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract ESM"}],"name":"esm","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract ESMFab"}],"name":"esmFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract Flapper"}],"name":"flap","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract FlapFab"}],"name":"flapFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract FlipFab"}],"name":"flipFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract Flopper"}],"name":"flop","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract FlopFab"}],"name":"flopFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"flip","internalType":"contract Flipper"},{"type":"address","name":"join","internalType":"address"}],"name":"ilks","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract Jug"}],"name":"jug","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract JugFab"}],"name":"jugFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract DSPause"}],"name":"pause","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract PauseFab"}],"name":"pauseFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract Pot"}],"name":"pot","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract PotFab"}],"name":"potFab","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"releaseAuth","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"releaseAuthFlip","inputs":[{"type":"bytes32","name":"ilk","internalType":"bytes32"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setAuthority","inputs":[{"type":"address","name":"authority_","internalType":"contract DSAuthority"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setOwner","inputs":[{"type":"address","name":"owner_","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract SpotFab"}],"name":"spotFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract Spotter"}],"name":"spotter","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"step","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract Vat"}],"name":"vat","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract VatFab"}],"name":"vatFab","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract Vow"}],"name":"vow","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract VowFab"}],"name":"vowFab","inputs":[],"constant":true}]
              

Contract Creation Code

Verify & Publish
0x6080604052601e805460ff1916905534801561001a57600080fd5b5060405161354b38038061354b83398181016040526101c081101561003e57600080fd5b50805160208201516040808401516060850151608086015160a087015160c088015160e08901516101008a01516101208b01516101408c01516101608d01516101808e01516101a0909e0151600180546001600160a01b031916339081179091559b519d9e9c9d9a9c999b989a97999698959794969395929491939290917fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a28d600260006101000a8154816001600160a01b0302191690836001600160a01b031602179055508c600360006101000a8154816001600160a01b0302191690836001600160a01b031602179055508b600460006101000a8154816001600160a01b0302191690836001600160a01b031602179055508a600560006101000a8154816001600160a01b0302191690836001600160a01b0316021790555089600660006101000a8154816001600160a01b0302191690836001600160a01b0316021790555088600760006101000a8154816001600160a01b0302191690836001600160a01b0316021790555087600860006101000a8154816001600160a01b0302191690836001600160a01b0316021790555086600960006101000a8154816001600160a01b0302191690836001600160a01b0316021790555085600a60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555084600b60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555083600c60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555082600d60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555081600e60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080600f60006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505050505050505050505050505061322a806103216000396000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c80638456cb5911610151578063c8e334a9116100c3578063e25fe17511610087578063e25fe175146104f1578063e48818131461050f578063eae131a914610517578063ef0add5b1461051f578063efbe1c1c14610527578063f4b9fa751461052f57610269565b8063c8e334a91461044c578063cc3f5ec114610454578063ce96193b1461047a578063d9638d36146104a6578063dcc91c9b146104e957610269565b8063b0a842a811610115578063b0a842a8146103d9578063b3731c781461040f578063b94fdb8e1461042c578063bbbb0d7b14610434578063bf7e214f1461043c578063c11645bc1461044457610269565b80638456cb59146103b157806384718d89146103b95780638da5cb5b146103c157806392ed5460146103c9578063af41b248146103d157610269565b80634ba2363a116101ea57806370402bb9116101ae57806370402bb914610337578063783e10fc1461033f5780637a9e5e4b146103475780637c91e1771461036d5780637d3fdfa11461037557806380e7cd89146103a957610269565b80634ba2363a146102fa5780635f35a49d14610302578063626cb3c51461030a57806364336cd01461031257806364b07f211461031a57610269565b80632e77468d116102315780632e77468d146102d257806336569e77146102da57806339c98420146102e257806339ca1def146102ea5780634a847390146102f257610269565b80630e01198b1461026e57806313af403514610292578063199bead4146102ba5780632800a568146102c257806329ced7a0146102ca575b600080fd5b610276610537565b604080516001600160a01b039092168252519081900360200190f35b6102b8600480360360208110156102a857600080fd5b50356001600160a01b0316610546565b005b6102766105eb565b6102b86105fa565b61027661082e565b61027661083d565b61027661084c565b61027661085b565b61027661086a565b610276610879565b610276610888565b610276610897565b6102766108a6565b6102766108b5565b6102b86004803603602081101561033057600080fd5b50356108c4565b6102b8610af6565b610276610f1b565b6102b86004803603602081101561035d57600080fd5b50356001600160a01b0316610f2a565b610276610fcb565b6102b86004803603606081101561038b57600080fd5b508035906001600160a01b0360208201358116916040013516610fda565b6102b8611609565b610276611885565b610276611894565b6102766118a3565b6102766118b2565b6102766118c1565b6102b8600480360360608110156103ef57600080fd5b506001600160a01b038135811691602081013590911690604001356118d0565b6102b86004803603602081101561042557600080fd5b5035611f4c565b610276611ff3565b610276612002565b610276612011565b610276612020565b61027661202f565b6102b86004803603602081101561046a57600080fd5b50356001600160a01b031661203e565b6102b86004803603604081101561049057600080fd5b50803590602001356001600160a01b03166124ab565b6104c3600480360360208110156104bc57600080fd5b5035612df3565b604080516001600160a01b03938416815291909216602082015281519081900390910190f35b6102b8612e19565b6104f9613078565b6040805160ff9092168252519081900360200190f35b610276613081565b610276613090565b61027661309f565b6102766130ae565b6102766130bd565b6016546001600160a01b031681565b61055c336000356001600160e01b0319166130cc565b61059b576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0383811691909117918290556040519116907fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a250565b6005546001600160a01b031681565b610610336000356001600160e01b0319166130cc565b61064f576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6010546001600160a01b0316156106a4576040805162461bcd60e51b815260206004820152601460248201527315905508185b1c9958591e4819195c1b1bde595960621b604482015290519081900360640190fd5b600260009054906101000a90046001600160a01b03166001600160a01b0316634b66490d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156106f457600080fd5b505af1158015610708573d6000803e3d6000fd5b505050506040513d602081101561071e57600080fd5b5051601080546001600160a01b0319166001600160a01b039283161790819055600b54604080516001621ae66160e11b0319815292841660048401525192169163ffca333e916024808201926020929091908290030181600087803b15801561078657600080fd5b505af115801561079a573d6000803e3d6000fd5b505050506040513d60208110156107b057600080fd5b5051601880546001600160a01b0319166001600160a01b039283161790819055601054604080516332fd71af60e11b81529284166004840152519216916365fae35e9160248082019260009290919082900301818387803b15801561081457600080fd5b505af1158015610828573d6000803e3d6000fd5b50505050565b6007546001600160a01b031681565b6018546001600160a01b031681565b6010546001600160a01b031681565b6008546001600160a01b031681565b6006546001600160a01b031681565b6002546001600160a01b031681565b6019546001600160a01b031681565b6003546001600160a01b031681565b6012546001600160a01b031681565b600e546001600160a01b031681565b6108da336000356001600160e01b0319166130cc565b610919576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6010546001600160a01b0316610964576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b60065460408051636667597360e11b81526004810184905290516001600160a01b039092169163ccceb2e6916024808201926020929091908290030181600087803b1580156109b257600080fd5b505af11580156109c6573d6000803e3d6000fd5b505050506040513d60208110156109dc57600080fd5b5051601480546001600160a01b0319166001600160a01b0392831617908190556007546010546040805163ac8f7a6b60e01b815291851660048301529284166024820152915192169163ac8f7a6b916044808201926020929091908290030181600087803b158015610a4d57600080fd5b505af1158015610a61573d6000803e3d6000fd5b505050506040513d6020811015610a7757600080fd5b5051601580546001600160a01b0319166001600160a01b039283161790819055601454604080516332fd71af60e11b81529284166004840152519216916365fae35e9160248082019260009290919082900301818387803b158015610adb57600080fd5b505af1158015610aef573d6000803e3d6000fd5b5050505050565b610b0c336000356001600160e01b0319166130cc565b610b4b576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b60105460408051639c52a7f160e01b815230600482015290516001600160a01b0390921691639c52a7f19160248082019260009290919082900301818387803b158015610b9757600080fd5b505af1158015610bab573d6000803e3d6000fd5b505060135460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610bfb57600080fd5b505af1158015610c0f573d6000803e3d6000fd5b505060125460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610c5f57600080fd5b505af1158015610c73573d6000803e3d6000fd5b505060115460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610cc357600080fd5b505af1158015610cd7573d6000803e3d6000fd5b505060195460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610d2757600080fd5b505af1158015610d3b573d6000803e3d6000fd5b505060145460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610d8b57600080fd5b505af1158015610d9f573d6000803e3d6000fd5b505060185460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610def57600080fd5b505af1158015610e03573d6000803e3d6000fd5b505060165460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610e5357600080fd5b505af1158015610e67573d6000803e3d6000fd5b505060175460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610eb757600080fd5b505af1158015610ecb573d6000803e3d6000fd5b5050601a5460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b15801561081457600080fd5b6009546001600160a01b031681565b610f40336000356001600160e01b0319166130cc565b610f7f576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b03838116919091178083556040519116917f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada491a250565b600a546001600160a01b031681565b610ff0336000356001600160e01b0319166130cc565b61102f576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b82611074576040805162461bcd60e51b815260206004820152601060248201526f4d697373696e6720696c6b206e616d6560801b604482015290519081900360640190fd5b6001600160a01b0382166110c6576040805162461bcd60e51b81526020600482015260146024820152734d697373696e67206a6f696e206164647265737360601b604482015290519081900360640190fd5b6001600160a01b038116611117576040805162461bcd60e51b81526020600482015260136024820152724d697373696e6720706970206164647265737360681b604482015290519081900360640190fd5b601c546001600160a01b0316611162576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b600a546010546040805163d711f46b60e01b81526001600160a01b039283166004820152602481018790529051919092169163d711f46b9160448083019260209291908290030181600087803b1580156111bb57600080fd5b505af11580156111cf573d6000803e3d6000fd5b505050506040513d60208110156111e557600080fd5b50516000848152601d602052604080822080546001600160a01b03199081166001600160a01b0395861617825560019091018054909116868516179055601854815163ebecb39d60e01b8152600481018890526207069760ec1b60248201528585166044820152915193169263ebecb39d9260648084019391929182900301818387803b15801561127557600080fd5b505af1158015611289573d6000803e3d6000fd5b50506013546000868152601d602052604080822054815163ebecb39d60e01b8152600481018a9052630666c69760e41b60248201526001600160a01b03918216604482015291519316945063ebecb39d93506064808201939182900301818387803b1580156112f757600080fd5b505af115801561130b573d6000803e3d6000fd5b505060105460408051633b66319560e01b81526004810188905290516001600160a01b039092169350633b663195925060248082019260009290919082900301818387803b15801561135c57600080fd5b505af1158015611370573d6000803e3d6000fd5b505060115460408051633b66319560e01b81526004810188905290516001600160a01b039092169350633b663195925060248082019260009290919082900301818387803b1580156113c157600080fd5b505af11580156113d5573d6000803e3d6000fd5b5050601054604080516332fd71af60e11b81526001600160a01b03878116600483015291519190921693506365fae35e9250602480830192600092919082900301818387803b15801561142757600080fd5b505af115801561143b573d6000803e3d6000fd5b5050506000848152601d60205260408082205460135482516332fd71af60e11b81526001600160a01b0391821660048201529251911693506365fae35e9260248084019391929182900301818387803b15801561149757600080fd5b505af11580156114ab573d6000803e3d6000fd5b5050506000848152601d602052604080822054601a5482516332fd71af60e11b81526001600160a01b0391821660048201529251911693506365fae35e9260248084019391929182900301818387803b15801561150757600080fd5b505af115801561151b573d6000803e3d6000fd5b5050506000848152601d602090815260409182902054601c54835163ec55688960e01b815293516001600160a01b0392831695506365fae35e94919092169263ec55688992600480840193829003018186803b15801561157a57600080fd5b505afa15801561158e573d6000803e3d6000fd5b505050506040513d60208110156115a457600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b1580156115ec57600080fd5b505af1158015611600573d6000803e3d6000fd5b50505050505050565b61161f336000356001600160e01b0319166130cc565b61165e576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6010546001600160a01b03166116a9576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b600354601054604080516338ab04d960e11b81526001600160a01b0392831660048201529051919092169163715609b29160248083019260209291908290030181600087803b1580156116fb57600080fd5b505af115801561170f573d6000803e3d6000fd5b505050506040513d602081101561172557600080fd5b5051601180546001600160a01b0319166001600160a01b03928316179055600c54601054604080516311b1f7ff60e21b815291841660048301525191909216916346c7dffc9160248083019260209291908290030181600087803b15801561178c57600080fd5b505af11580156117a0573d6000803e3d6000fd5b505050506040513d60208110156117b657600080fd5b5051601980546001600160a01b0319166001600160a01b03928316179055601054601154604080516332fd71af60e11b815291841660048301525191909216916365fae35e91602480830192600092919082900301818387803b15801561181c57600080fd5b505af1158015611830573d6000803e3d6000fd5b5050601054601954604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b15801561081457600080fd5b601c546001600160a01b031681565b6011546001600160a01b031681565b6001546001600160a01b031681565b600b546001600160a01b031681565b601b546001600160a01b031681565b6118e6336000356001600160e01b0319166130cc565b611925576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6013546001600160a01b0316611970576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b600d60009054906101000a90046001600160a01b03166001600160a01b0316631e2616996040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156119c057600080fd5b505af11580156119d4573d6000803e3d6000fd5b505050506040513d60208110156119ea57600080fd5b5051601a80546001600160a01b0319166001600160a01b0392831617908190556010546040805163d4e8be8360e01b8152621d985d60ea1b6004820152918416602483015251919092169163d4e8be8391604480830192600092919082900301818387803b158015611a5b57600080fd5b505af1158015611a6f573d6000803e3d6000fd5b5050601a546013546040805163d4e8be8360e01b81526218d85d60ea1b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b158015611ad057600080fd5b505af1158015611ae4573d6000803e3d6000fd5b5050601a546012546040805163d4e8be8360e01b815262766f7760e81b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b158015611b4557600080fd5b505af1158015611b59573d6000803e3d6000fd5b5050601a546019546040805163d4e8be8360e01b8152621c1bdd60ea1b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b158015611bba57600080fd5b505af1158015611bce573d6000803e3d6000fd5b5050601a546018546040805163d4e8be8360e01b8152631cdc1bdd60e21b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b158015611c3057600080fd5b505af1158015611c44573d6000803e3d6000fd5b5050601054601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611c9957600080fd5b505af1158015611cad573d6000803e3d6000fd5b5050601354601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611d0257600080fd5b505af1158015611d16573d6000803e3d6000fd5b5050601254601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611d6b57600080fd5b505af1158015611d7f573d6000803e3d6000fd5b5050601954601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611dd457600080fd5b505af1158015611de8573d6000803e3d6000fd5b5050601854601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b5050600e54601a546040805163085375ed60e31b81526001600160a01b0389811660048301529283166024820152878316604482015260648101879052905191909216935063429baf68925060848083019260209291908290030181600087803b158015611ebe57600080fd5b505af1158015611ed2573d6000803e3d6000fd5b505050506040513d6020811015611ee857600080fd5b5051601b80546001600160a01b0319166001600160a01b039283161790819055601a54604080516332fd71af60e11b81529284166004840152519216916365fae35e9160248082019260009290919082900301818387803b1580156115ec57600080fd5b611f62336000356001600160e01b0319166130cc565b611fa1576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6000818152601d6020526040808220548151639c52a7f160e01b815230600482015291516001600160a01b0390911692639c52a7f1926024808201939182900301818387803b158015610adb57600080fd5b6004546001600160a01b031681565b6017546001600160a01b031681565b6000546001600160a01b031681565b6015546001600160a01b031681565b600f546001600160a01b031681565b612054336000356001600160e01b0319166130cc565b612093576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6001600160a01b0381166120e4576040805162461bcd60e51b81526020600482015260136024820152724d697373696e6720474f56206164647265737360681b604482015290519081900360640190fd5b6011546001600160a01b031661212f576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b6008546010546040805163762e10e160e11b81526001600160a01b03928316600482015284831660248201529051919092169163ec5c21c29160448083019260209291908290030181600087803b15801561218957600080fd5b505af115801561219d573d6000803e3d6000fd5b505050506040513d60208110156121b357600080fd5b5051601680546001600160a01b0319166001600160a01b0392831617905560095460105460408051633706fd6760e21b81529184166004830152848416602483015251919092169163dc1bf59c9160448083019260209291908290030181600087803b15801561222257600080fd5b505af1158015612236573d6000803e3d6000fd5b505050506040513d602081101561224c57600080fd5b5051601780546001600160a01b0319166001600160a01b0392831617908190556004805460105460165460408051638dfc3d3f60e01b8152928716948301949094528516602482015292841660448401529051921691638dfc3d3f916064808201926020929091908290030181600087803b1580156122ca57600080fd5b505af11580156122de573d6000803e3d6000fd5b505050506040513d60208110156122f457600080fd5b5051601280546001600160a01b0319166001600160a01b0392831617908190556011546040805163d4e8be8360e01b815262766f7760e81b600482015292841660248401525192169163d4e8be839160448082019260009290919082900301818387803b15801561236457600080fd5b505af1158015612378573d6000803e3d6000fd5b50506019546012546040805163d4e8be8360e01b815262766f7760e81b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b1580156123d957600080fd5b505af11580156123ed573d6000803e3d6000fd5b5050601654601254604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b15801561244257600080fd5b505af1158015612456573d6000803e3d6000fd5b5050601754601254604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015610adb57600080fd5b6124c1336000356001600160e01b0319166130cc565b612500576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6014546001600160a01b031661254b576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b601a546001600160a01b0316612596576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b600f5460408051632797fa5360e11b8152600481018590526000602482018190526001600160a01b03858116604484015292519290931692634f2ff4a6926064808401936020939083900390910190829087803b1580156125f657600080fd5b505af115801561260a573d6000803e3d6000fd5b505050506040513d602081101561262057600080fd5b5051601c80546001600160a01b0319166001600160a01b0392831617908190556010546040805163ec55688960e01b81529051918416936365fae35e93169163ec55688991600480820192602092909190829003018186803b15801561268557600080fd5b505afa158015612699573d6000803e3d6000fd5b505050506040513d60208110156126af57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b1580156126f757600080fd5b505af115801561270b573d6000803e3d6000fd5b5050601354601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b15801561276157600080fd5b505afa158015612775573d6000803e3d6000fd5b505050506040513d602081101561278b57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b1580156127d357600080fd5b505af11580156127e7573d6000803e3d6000fd5b5050601254601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b15801561283d57600080fd5b505afa158015612851573d6000803e3d6000fd5b505050506040513d602081101561286757600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b1580156128af57600080fd5b505af11580156128c3573d6000803e3d6000fd5b5050601154601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b15801561291957600080fd5b505afa15801561292d573d6000803e3d6000fd5b505050506040513d602081101561294357600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b15801561298b57600080fd5b505af115801561299f573d6000803e3d6000fd5b5050601954601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b1580156129f557600080fd5b505afa158015612a09573d6000803e3d6000fd5b505050506040513d6020811015612a1f57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612a6757600080fd5b505af1158015612a7b573d6000803e3d6000fd5b5050601854601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b158015612ad157600080fd5b505afa158015612ae5573d6000803e3d6000fd5b505050506040513d6020811015612afb57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612b4357600080fd5b505af1158015612b57573d6000803e3d6000fd5b5050601654601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b158015612bad57600080fd5b505afa158015612bc1573d6000803e3d6000fd5b505050506040513d6020811015612bd757600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612c1f57600080fd5b505af1158015612c33573d6000803e3d6000fd5b5050601754601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b158015612c8957600080fd5b505afa158015612c9d573d6000803e3d6000fd5b505050506040513d6020811015612cb357600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612cfb57600080fd5b505af1158015612d0f573d6000803e3d6000fd5b5050601a54601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b158015612d6557600080fd5b505afa158015612d79573d6000803e3d6000fd5b505050506040513d6020811015612d8f57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612dd757600080fd5b505af1158015612deb573d6000803e3d6000fd5b505050505050565b601d60205260009081526040902080546001909101546001600160a01b03918216911682565b612e2f336000356001600160e01b0319166130cc565b612e6e576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6012546001600160a01b0316612eb9576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b6005546010546040805163f3de0c7360e01b81526001600160a01b0392831660048201529051919092169163f3de0c739160248083019260209291908290030181600087803b158015612f0b57600080fd5b505af1158015612f1f573d6000803e3d6000fd5b505050506040513d6020811015612f3557600080fd5b5051601380546001600160a01b0319166001600160a01b0392831617908190556012546040805163d4e8be8360e01b815262766f7760e81b6004820152918416602483015251919092169163d4e8be8391604480830192600092919082900301818387803b158015612fa657600080fd5b505af1158015612fba573d6000803e3d6000fd5b5050601054601354604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b15801561300f57600080fd5b505af1158015613023573d6000803e3d6000fd5b5050601254601354604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b15801561081457600080fd5b601e5460ff1681565b6013546001600160a01b031681565b600c546001600160a01b031681565b600d546001600160a01b031681565b601a546001600160a01b031681565b6014546001600160a01b031681565b60006001600160a01b0383163014156130e7575060016131af565b6001546001600160a01b0384811691161415613105575060016131af565b6000546001600160a01b031661311d575060006131af565b6000546040805163b700961360e01b81526001600160a01b0386811660048301523060248301526001600160e01b0319861660448301529151919092169163b7009613916064808301926020929190829003018186803b15801561318057600080fd5b505afa158015613194573d6000803e3d6000fd5b505050506040513d60208110156131aa57600080fd5b505190505b9291505056fe4d697373696e672070726576696f75732073746570000000000000000000000064732d617574682d756e617574686f72697a6564000000000000000000000000a265627a7a72315820cfe73dd1e4d37386716e919548d8dae4a01254c98e363a63f2b57d562975ce3864736f6c634300050c0032000000000000000000000000403689148fa98a5a6fdcc0b984914ae968d788e500000000000000000000000045f0a929889ec8cc2d5b8cd79ab55e3279945cde00000000000000000000000068322ca1a9aeb8c1d610b5fc8a8920aa0fba423b000000000000000000000000a9ee75d81d78c36c4163004e6cc7a988eec9433e000000000000000000000000b5b06a16621616875a6c2637948bf98ea57c58fa00000000000000000000000064a84e558192dd025f3a96775fee8fb530f27177000000000000000000000000d27a5f3416d8791fc238c148c93630d9e3c882e5000000000000000000000000c41c4759f67ff54c7a7314d155f40fc6504f5d28000000000000000000000000bab4fbea257abbfe84f4588d4eedc43656e46fc5000000000000000000000000dedd12bcb045c02b2fe11031c2b269bcde4574100000000000000000000000001a5ee7c64cf874c735968e3a42fa13f1c03427f9000000000000000000000000fd34e2c588a519f173d54be539a56fed4830ba530000000000000000000000002e278c5fb9231581f4284a253cc5728b6acd372d00000000000000000000000084f2b4648990d93c0f478d5d82d3c38d98a4ee91

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106102695760003560e01c80638456cb5911610151578063c8e334a9116100c3578063e25fe17511610087578063e25fe175146104f1578063e48818131461050f578063eae131a914610517578063ef0add5b1461051f578063efbe1c1c14610527578063f4b9fa751461052f57610269565b8063c8e334a91461044c578063cc3f5ec114610454578063ce96193b1461047a578063d9638d36146104a6578063dcc91c9b146104e957610269565b8063b0a842a811610115578063b0a842a8146103d9578063b3731c781461040f578063b94fdb8e1461042c578063bbbb0d7b14610434578063bf7e214f1461043c578063c11645bc1461044457610269565b80638456cb59146103b157806384718d89146103b95780638da5cb5b146103c157806392ed5460146103c9578063af41b248146103d157610269565b80634ba2363a116101ea57806370402bb9116101ae57806370402bb914610337578063783e10fc1461033f5780637a9e5e4b146103475780637c91e1771461036d5780637d3fdfa11461037557806380e7cd89146103a957610269565b80634ba2363a146102fa5780635f35a49d14610302578063626cb3c51461030a57806364336cd01461031257806364b07f211461031a57610269565b80632e77468d116102315780632e77468d146102d257806336569e77146102da57806339c98420146102e257806339ca1def146102ea5780634a847390146102f257610269565b80630e01198b1461026e57806313af403514610292578063199bead4146102ba5780632800a568146102c257806329ced7a0146102ca575b600080fd5b610276610537565b604080516001600160a01b039092168252519081900360200190f35b6102b8600480360360208110156102a857600080fd5b50356001600160a01b0316610546565b005b6102766105eb565b6102b86105fa565b61027661082e565b61027661083d565b61027661084c565b61027661085b565b61027661086a565b610276610879565b610276610888565b610276610897565b6102766108a6565b6102766108b5565b6102b86004803603602081101561033057600080fd5b50356108c4565b6102b8610af6565b610276610f1b565b6102b86004803603602081101561035d57600080fd5b50356001600160a01b0316610f2a565b610276610fcb565b6102b86004803603606081101561038b57600080fd5b508035906001600160a01b0360208201358116916040013516610fda565b6102b8611609565b610276611885565b610276611894565b6102766118a3565b6102766118b2565b6102766118c1565b6102b8600480360360608110156103ef57600080fd5b506001600160a01b038135811691602081013590911690604001356118d0565b6102b86004803603602081101561042557600080fd5b5035611f4c565b610276611ff3565b610276612002565b610276612011565b610276612020565b61027661202f565b6102b86004803603602081101561046a57600080fd5b50356001600160a01b031661203e565b6102b86004803603604081101561049057600080fd5b50803590602001356001600160a01b03166124ab565b6104c3600480360360208110156104bc57600080fd5b5035612df3565b604080516001600160a01b03938416815291909216602082015281519081900390910190f35b6102b8612e19565b6104f9613078565b6040805160ff9092168252519081900360200190f35b610276613081565b610276613090565b61027661309f565b6102766130ae565b6102766130bd565b6016546001600160a01b031681565b61055c336000356001600160e01b0319166130cc565b61059b576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0383811691909117918290556040519116907fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a250565b6005546001600160a01b031681565b610610336000356001600160e01b0319166130cc565b61064f576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6010546001600160a01b0316156106a4576040805162461bcd60e51b815260206004820152601460248201527315905508185b1c9958591e4819195c1b1bde595960621b604482015290519081900360640190fd5b600260009054906101000a90046001600160a01b03166001600160a01b0316634b66490d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156106f457600080fd5b505af1158015610708573d6000803e3d6000fd5b505050506040513d602081101561071e57600080fd5b5051601080546001600160a01b0319166001600160a01b039283161790819055600b54604080516001621ae66160e11b0319815292841660048401525192169163ffca333e916024808201926020929091908290030181600087803b15801561078657600080fd5b505af115801561079a573d6000803e3d6000fd5b505050506040513d60208110156107b057600080fd5b5051601880546001600160a01b0319166001600160a01b039283161790819055601054604080516332fd71af60e11b81529284166004840152519216916365fae35e9160248082019260009290919082900301818387803b15801561081457600080fd5b505af1158015610828573d6000803e3d6000fd5b50505050565b6007546001600160a01b031681565b6018546001600160a01b031681565b6010546001600160a01b031681565b6008546001600160a01b031681565b6006546001600160a01b031681565b6002546001600160a01b031681565b6019546001600160a01b031681565b6003546001600160a01b031681565b6012546001600160a01b031681565b600e546001600160a01b031681565b6108da336000356001600160e01b0319166130cc565b610919576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6010546001600160a01b0316610964576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b60065460408051636667597360e11b81526004810184905290516001600160a01b039092169163ccceb2e6916024808201926020929091908290030181600087803b1580156109b257600080fd5b505af11580156109c6573d6000803e3d6000fd5b505050506040513d60208110156109dc57600080fd5b5051601480546001600160a01b0319166001600160a01b0392831617908190556007546010546040805163ac8f7a6b60e01b815291851660048301529284166024820152915192169163ac8f7a6b916044808201926020929091908290030181600087803b158015610a4d57600080fd5b505af1158015610a61573d6000803e3d6000fd5b505050506040513d6020811015610a7757600080fd5b5051601580546001600160a01b0319166001600160a01b039283161790819055601454604080516332fd71af60e11b81529284166004840152519216916365fae35e9160248082019260009290919082900301818387803b158015610adb57600080fd5b505af1158015610aef573d6000803e3d6000fd5b5050505050565b610b0c336000356001600160e01b0319166130cc565b610b4b576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b60105460408051639c52a7f160e01b815230600482015290516001600160a01b0390921691639c52a7f19160248082019260009290919082900301818387803b158015610b9757600080fd5b505af1158015610bab573d6000803e3d6000fd5b505060135460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610bfb57600080fd5b505af1158015610c0f573d6000803e3d6000fd5b505060125460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610c5f57600080fd5b505af1158015610c73573d6000803e3d6000fd5b505060115460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610cc357600080fd5b505af1158015610cd7573d6000803e3d6000fd5b505060195460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610d2757600080fd5b505af1158015610d3b573d6000803e3d6000fd5b505060145460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610d8b57600080fd5b505af1158015610d9f573d6000803e3d6000fd5b505060185460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610def57600080fd5b505af1158015610e03573d6000803e3d6000fd5b505060165460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610e5357600080fd5b505af1158015610e67573d6000803e3d6000fd5b505060175460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b158015610eb757600080fd5b505af1158015610ecb573d6000803e3d6000fd5b5050601a5460408051639c52a7f160e01b815230600482015290516001600160a01b039092169350639c52a7f1925060248082019260009290919082900301818387803b15801561081457600080fd5b6009546001600160a01b031681565b610f40336000356001600160e01b0319166130cc565b610f7f576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b03838116919091178083556040519116917f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada491a250565b600a546001600160a01b031681565b610ff0336000356001600160e01b0319166130cc565b61102f576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b82611074576040805162461bcd60e51b815260206004820152601060248201526f4d697373696e6720696c6b206e616d6560801b604482015290519081900360640190fd5b6001600160a01b0382166110c6576040805162461bcd60e51b81526020600482015260146024820152734d697373696e67206a6f696e206164647265737360601b604482015290519081900360640190fd5b6001600160a01b038116611117576040805162461bcd60e51b81526020600482015260136024820152724d697373696e6720706970206164647265737360681b604482015290519081900360640190fd5b601c546001600160a01b0316611162576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b600a546010546040805163d711f46b60e01b81526001600160a01b039283166004820152602481018790529051919092169163d711f46b9160448083019260209291908290030181600087803b1580156111bb57600080fd5b505af11580156111cf573d6000803e3d6000fd5b505050506040513d60208110156111e557600080fd5b50516000848152601d602052604080822080546001600160a01b03199081166001600160a01b0395861617825560019091018054909116868516179055601854815163ebecb39d60e01b8152600481018890526207069760ec1b60248201528585166044820152915193169263ebecb39d9260648084019391929182900301818387803b15801561127557600080fd5b505af1158015611289573d6000803e3d6000fd5b50506013546000868152601d602052604080822054815163ebecb39d60e01b8152600481018a9052630666c69760e41b60248201526001600160a01b03918216604482015291519316945063ebecb39d93506064808201939182900301818387803b1580156112f757600080fd5b505af115801561130b573d6000803e3d6000fd5b505060105460408051633b66319560e01b81526004810188905290516001600160a01b039092169350633b663195925060248082019260009290919082900301818387803b15801561135c57600080fd5b505af1158015611370573d6000803e3d6000fd5b505060115460408051633b66319560e01b81526004810188905290516001600160a01b039092169350633b663195925060248082019260009290919082900301818387803b1580156113c157600080fd5b505af11580156113d5573d6000803e3d6000fd5b5050601054604080516332fd71af60e11b81526001600160a01b03878116600483015291519190921693506365fae35e9250602480830192600092919082900301818387803b15801561142757600080fd5b505af115801561143b573d6000803e3d6000fd5b5050506000848152601d60205260408082205460135482516332fd71af60e11b81526001600160a01b0391821660048201529251911693506365fae35e9260248084019391929182900301818387803b15801561149757600080fd5b505af11580156114ab573d6000803e3d6000fd5b5050506000848152601d602052604080822054601a5482516332fd71af60e11b81526001600160a01b0391821660048201529251911693506365fae35e9260248084019391929182900301818387803b15801561150757600080fd5b505af115801561151b573d6000803e3d6000fd5b5050506000848152601d602090815260409182902054601c54835163ec55688960e01b815293516001600160a01b0392831695506365fae35e94919092169263ec55688992600480840193829003018186803b15801561157a57600080fd5b505afa15801561158e573d6000803e3d6000fd5b505050506040513d60208110156115a457600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b1580156115ec57600080fd5b505af1158015611600573d6000803e3d6000fd5b50505050505050565b61161f336000356001600160e01b0319166130cc565b61165e576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6010546001600160a01b03166116a9576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b600354601054604080516338ab04d960e11b81526001600160a01b0392831660048201529051919092169163715609b29160248083019260209291908290030181600087803b1580156116fb57600080fd5b505af115801561170f573d6000803e3d6000fd5b505050506040513d602081101561172557600080fd5b5051601180546001600160a01b0319166001600160a01b03928316179055600c54601054604080516311b1f7ff60e21b815291841660048301525191909216916346c7dffc9160248083019260209291908290030181600087803b15801561178c57600080fd5b505af11580156117a0573d6000803e3d6000fd5b505050506040513d60208110156117b657600080fd5b5051601980546001600160a01b0319166001600160a01b03928316179055601054601154604080516332fd71af60e11b815291841660048301525191909216916365fae35e91602480830192600092919082900301818387803b15801561181c57600080fd5b505af1158015611830573d6000803e3d6000fd5b5050601054601954604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b15801561081457600080fd5b601c546001600160a01b031681565b6011546001600160a01b031681565b6001546001600160a01b031681565b600b546001600160a01b031681565b601b546001600160a01b031681565b6118e6336000356001600160e01b0319166130cc565b611925576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6013546001600160a01b0316611970576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b600d60009054906101000a90046001600160a01b03166001600160a01b0316631e2616996040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156119c057600080fd5b505af11580156119d4573d6000803e3d6000fd5b505050506040513d60208110156119ea57600080fd5b5051601a80546001600160a01b0319166001600160a01b0392831617908190556010546040805163d4e8be8360e01b8152621d985d60ea1b6004820152918416602483015251919092169163d4e8be8391604480830192600092919082900301818387803b158015611a5b57600080fd5b505af1158015611a6f573d6000803e3d6000fd5b5050601a546013546040805163d4e8be8360e01b81526218d85d60ea1b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b158015611ad057600080fd5b505af1158015611ae4573d6000803e3d6000fd5b5050601a546012546040805163d4e8be8360e01b815262766f7760e81b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b158015611b4557600080fd5b505af1158015611b59573d6000803e3d6000fd5b5050601a546019546040805163d4e8be8360e01b8152621c1bdd60ea1b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b158015611bba57600080fd5b505af1158015611bce573d6000803e3d6000fd5b5050601a546018546040805163d4e8be8360e01b8152631cdc1bdd60e21b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b158015611c3057600080fd5b505af1158015611c44573d6000803e3d6000fd5b5050601054601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611c9957600080fd5b505af1158015611cad573d6000803e3d6000fd5b5050601354601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611d0257600080fd5b505af1158015611d16573d6000803e3d6000fd5b5050601254601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611d6b57600080fd5b505af1158015611d7f573d6000803e3d6000fd5b5050601954601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611dd457600080fd5b505af1158015611de8573d6000803e3d6000fd5b5050601854601a54604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b5050600e54601a546040805163085375ed60e31b81526001600160a01b0389811660048301529283166024820152878316604482015260648101879052905191909216935063429baf68925060848083019260209291908290030181600087803b158015611ebe57600080fd5b505af1158015611ed2573d6000803e3d6000fd5b505050506040513d6020811015611ee857600080fd5b5051601b80546001600160a01b0319166001600160a01b039283161790819055601a54604080516332fd71af60e11b81529284166004840152519216916365fae35e9160248082019260009290919082900301818387803b1580156115ec57600080fd5b611f62336000356001600160e01b0319166130cc565b611fa1576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6000818152601d6020526040808220548151639c52a7f160e01b815230600482015291516001600160a01b0390911692639c52a7f1926024808201939182900301818387803b158015610adb57600080fd5b6004546001600160a01b031681565b6017546001600160a01b031681565b6000546001600160a01b031681565b6015546001600160a01b031681565b600f546001600160a01b031681565b612054336000356001600160e01b0319166130cc565b612093576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6001600160a01b0381166120e4576040805162461bcd60e51b81526020600482015260136024820152724d697373696e6720474f56206164647265737360681b604482015290519081900360640190fd5b6011546001600160a01b031661212f576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b6008546010546040805163762e10e160e11b81526001600160a01b03928316600482015284831660248201529051919092169163ec5c21c29160448083019260209291908290030181600087803b15801561218957600080fd5b505af115801561219d573d6000803e3d6000fd5b505050506040513d60208110156121b357600080fd5b5051601680546001600160a01b0319166001600160a01b0392831617905560095460105460408051633706fd6760e21b81529184166004830152848416602483015251919092169163dc1bf59c9160448083019260209291908290030181600087803b15801561222257600080fd5b505af1158015612236573d6000803e3d6000fd5b505050506040513d602081101561224c57600080fd5b5051601780546001600160a01b0319166001600160a01b0392831617908190556004805460105460165460408051638dfc3d3f60e01b8152928716948301949094528516602482015292841660448401529051921691638dfc3d3f916064808201926020929091908290030181600087803b1580156122ca57600080fd5b505af11580156122de573d6000803e3d6000fd5b505050506040513d60208110156122f457600080fd5b5051601280546001600160a01b0319166001600160a01b0392831617908190556011546040805163d4e8be8360e01b815262766f7760e81b600482015292841660248401525192169163d4e8be839160448082019260009290919082900301818387803b15801561236457600080fd5b505af1158015612378573d6000803e3d6000fd5b50506019546012546040805163d4e8be8360e01b815262766f7760e81b60048201526001600160a01b039283166024820152905191909216935063d4e8be839250604480830192600092919082900301818387803b1580156123d957600080fd5b505af11580156123ed573d6000803e3d6000fd5b5050601654601254604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b15801561244257600080fd5b505af1158015612456573d6000803e3d6000fd5b5050601754601254604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b158015610adb57600080fd5b6124c1336000356001600160e01b0319166130cc565b612500576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6014546001600160a01b031661254b576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b601a546001600160a01b0316612596576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b600f5460408051632797fa5360e11b8152600481018590526000602482018190526001600160a01b03858116604484015292519290931692634f2ff4a6926064808401936020939083900390910190829087803b1580156125f657600080fd5b505af115801561260a573d6000803e3d6000fd5b505050506040513d602081101561262057600080fd5b5051601c80546001600160a01b0319166001600160a01b0392831617908190556010546040805163ec55688960e01b81529051918416936365fae35e93169163ec55688991600480820192602092909190829003018186803b15801561268557600080fd5b505afa158015612699573d6000803e3d6000fd5b505050506040513d60208110156126af57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b1580156126f757600080fd5b505af115801561270b573d6000803e3d6000fd5b5050601354601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b15801561276157600080fd5b505afa158015612775573d6000803e3d6000fd5b505050506040513d602081101561278b57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b1580156127d357600080fd5b505af11580156127e7573d6000803e3d6000fd5b5050601254601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b15801561283d57600080fd5b505afa158015612851573d6000803e3d6000fd5b505050506040513d602081101561286757600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b1580156128af57600080fd5b505af11580156128c3573d6000803e3d6000fd5b5050601154601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b15801561291957600080fd5b505afa15801561292d573d6000803e3d6000fd5b505050506040513d602081101561294357600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b15801561298b57600080fd5b505af115801561299f573d6000803e3d6000fd5b5050601954601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b1580156129f557600080fd5b505afa158015612a09573d6000803e3d6000fd5b505050506040513d6020811015612a1f57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612a6757600080fd5b505af1158015612a7b573d6000803e3d6000fd5b5050601854601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b158015612ad157600080fd5b505afa158015612ae5573d6000803e3d6000fd5b505050506040513d6020811015612afb57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612b4357600080fd5b505af1158015612b57573d6000803e3d6000fd5b5050601654601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b158015612bad57600080fd5b505afa158015612bc1573d6000803e3d6000fd5b505050506040513d6020811015612bd757600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612c1f57600080fd5b505af1158015612c33573d6000803e3d6000fd5b5050601754601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b158015612c8957600080fd5b505afa158015612c9d573d6000803e3d6000fd5b505050506040513d6020811015612cb357600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612cfb57600080fd5b505af1158015612d0f573d6000803e3d6000fd5b5050601a54601c546040805163ec55688960e01b815290516001600160a01b0393841695506365fae35e9450919092169163ec556889916004808301926020929190829003018186803b158015612d6557600080fd5b505afa158015612d79573d6000803e3d6000fd5b505050506040513d6020811015612d8f57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015251602480830192600092919082900301818387803b158015612dd757600080fd5b505af1158015612deb573d6000803e3d6000fd5b505050505050565b601d60205260009081526040902080546001909101546001600160a01b03918216911682565b612e2f336000356001600160e01b0319166130cc565b612e6e576040805162461bcd60e51b815260206004820152601460248201526000805160206131d6833981519152604482015290519081900360640190fd5b6012546001600160a01b0316612eb9576040805162461bcd60e51b815260206004820152601560248201526000805160206131b6833981519152604482015290519081900360640190fd5b6005546010546040805163f3de0c7360e01b81526001600160a01b0392831660048201529051919092169163f3de0c739160248083019260209291908290030181600087803b158015612f0b57600080fd5b505af1158015612f1f573d6000803e3d6000fd5b505050506040513d6020811015612f3557600080fd5b5051601380546001600160a01b0319166001600160a01b0392831617908190556012546040805163d4e8be8360e01b815262766f7760e81b6004820152918416602483015251919092169163d4e8be8391604480830192600092919082900301818387803b158015612fa657600080fd5b505af1158015612fba573d6000803e3d6000fd5b5050601054601354604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b15801561300f57600080fd5b505af1158015613023573d6000803e3d6000fd5b5050601254601354604080516332fd71af60e11b81526001600160a01b03928316600482015290519190921693506365fae35e9250602480830192600092919082900301818387803b15801561081457600080fd5b601e5460ff1681565b6013546001600160a01b031681565b600c546001600160a01b031681565b600d546001600160a01b031681565b601a546001600160a01b031681565b6014546001600160a01b031681565b60006001600160a01b0383163014156130e7575060016131af565b6001546001600160a01b0384811691161415613105575060016131af565b6000546001600160a01b031661311d575060006131af565b6000546040805163b700961360e01b81526001600160a01b0386811660048301523060248301526001600160e01b0319861660448301529151919092169163b7009613916064808301926020929190829003018186803b15801561318057600080fd5b505afa158015613194573d6000803e3d6000fd5b505050506040513d60208110156131aa57600080fd5b505190505b9291505056fe4d697373696e672070726576696f75732073746570000000000000000000000064732d617574682d756e617574686f72697a6564000000000000000000000000a265627a7a72315820cfe73dd1e4d37386716e919548d8dae4a01254c98e363a63f2b57d562975ce3864736f6c634300050c0032