Contract 0x389a34ff795Fa0b63F325486560FC6666A0d81A7

 
Ad
Crypto.com
Txn Hash
Block
From
To
Value
0xa9d19f42f06b86e8a09871f13814ef047432c89c2eef8b7fd8bb2a45e8f8c225119270802021-02-25 15:11:401 day 15 hrs ago0x5cab1e5286529370880776461c53a0e47d74fb63 IN 0x389a34ff795fa0b63f325486560fc6666a0d81a70 Ether0.66657375193
0xc587110d559a6a46251b52ea7b2ebef8e3908d8a432c4a03a6c4ab6d50f00f58119140172021-02-23 15:09:113 days 15 hrs ago0x5cab1e5286529370880776461c53a0e47d74fb63 IN 0x389a34ff795fa0b63f325486560fc6666a0d81a70 Ether0.042096436508
0x28687cbd658993255245ddc8be53846695fa95ec227a4cbf97c3685bb145e80d118886992021-02-19 17:26:547 days 12 hrs ago0xda0fab0700a4389f6e6679abab1692b4601ce9bf IN  Contract Creation0 Ether0.70770855721250.01
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x28687cbd658993255245ddc8be53846695fa95ec227a4cbf97c3685bb145e80d118886992021-02-19 17:26:547 days 12 hrs ago 0x389a34ff795fa0b63f325486560fc6666a0d81a7  Contract Creation0 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DssSpell

Compiler Version
v0.6.11+commit.5ef660b1

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU AGPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-02-19
*/

// SPDX-License-Identifier: AGPL-3.0-or-later
// hevm: flattened sources of src/DssSpell.sol
pragma solidity =0.6.11 >=0.5.12 >=0.6.11 <0.7.0;

////// lib/dss-exec-lib/src/CollateralOpts.sol
/* pragma solidity ^0.6.11; */

struct CollateralOpts {
    bytes32 ilk;
    address gem;
    address join;
    address flip;
    address pip;
    bool    isLiquidatable;
    bool    isOSM;
    bool    whitelistOSM;
    uint256 ilkDebtCeiling;
    uint256 minVaultAmount;
    uint256 maxLiquidationAmount;
    uint256 liquidationPenalty;
    uint256 ilkStabilityFee;
    uint256 bidIncrease;
    uint256 bidDuration;
    uint256 auctionDuration;
    uint256 liquidationRatio;
}

////// lib/dss-exec-lib/src/DssExecLib.sol
//
// DssExecLib.sol -- MakerDAO Executive Spellcrafting Library
//
// Copyright (C) 2020 Maker Ecosystem Growth Holdings, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
/* pragma solidity ^0.6.11; */

interface Initializable {
    function init(bytes32) external;
}

interface Authorizable {
    function rely(address) external;
    function deny(address) external;
}

interface Fileable {
    function file(bytes32, address) external;
    function file(bytes32, uint256) external;
    function file(bytes32, bytes32, uint256) external;
    function file(bytes32, bytes32, address) external;
}

interface Drippable {
    function drip() external returns (uint256);
    function drip(bytes32) external returns (uint256);
}

interface Pricing {
    function poke(bytes32) external;
}

interface ERC20 {
    function decimals() external returns (uint8);
}

interface DssVat {
    function hope(address) external;
    function nope(address) external;
    function ilks(bytes32) external returns (uint256 Art, uint256 rate, uint256 spot, uint256 line, uint256 dust);
    function Line() external view returns (uint256);
    function suck(address, address, uint) external;
}

interface AuctionLike {
    function vat() external returns (address);
    function cat() external returns (address); // Only flip
    function beg() external returns (uint256);
    function pad() external returns (uint256); // Only flop
    function ttl() external returns (uint256);
    function tau() external returns (uint256);
    function ilk() external returns (bytes32); // Only flip
    function gem() external returns (bytes32); // Only flap/flop
}

interface JoinLike {
    function vat() external returns (address);
    function ilk() external returns (bytes32);
    function gem() external returns (address);
    function dec() external returns (uint256);
    function join(address, uint) external;
    function exit(address, uint) external;
}

// Includes Median and OSM functions
interface OracleLike_2 {
    function src() external view returns (address);
    function lift(address[] calldata) external;
    function drop(address[] calldata) external;
    function setBar(uint256) external;
    function kiss(address) external;
    function diss(address) external;
    function kiss(address[] calldata) external;
    function diss(address[] calldata) external;
}

interface MomLike {
    function setOsm(bytes32, address) external;
}

interface RegistryLike {
    function add(address) external;
    function info(bytes32) external view returns (
        string memory, string memory, uint256, address, address, address, address
    );
    function ilkData(bytes32) external view returns (
        uint256       pos,
        address       gem,
        address       pip,
        address       join,
        address       flip,
        uint256       dec,
        string memory name,
        string memory symbol
    );
}

// https://github.com/makerdao/dss-chain-log
interface ChainlogLike {
    function setVersion(string calldata) external;
    function setIPFS(string calldata) external;
    function setSha256sum(string calldata) external;
    function getAddress(bytes32) external view returns (address);
    function setAddress(bytes32, address) external;
    function removeAddress(bytes32) external;
}

interface IAMLike {
    function ilks(bytes32) external view returns (uint256,uint256,uint48,uint48,uint48);
    function setIlk(bytes32,uint256,uint256,uint256) external;
    function remIlk(bytes32) external;
    function exec(bytes32) external returns (uint256);
}


library DssExecLib {

    /*****************/
    /*** Constants ***/
    /*****************/
    address constant public LOG = 0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F;

    uint256 constant internal WAD      = 10 ** 18;
    uint256 constant internal RAY      = 10 ** 27;
    uint256 constant internal RAD      = 10 ** 45;
    uint256 constant internal THOUSAND = 10 ** 3;
    uint256 constant internal MILLION  = 10 ** 6;

    uint256 constant internal BPS_ONE_PCT             = 100;
    uint256 constant internal BPS_ONE_HUNDRED_PCT     = 100 * BPS_ONE_PCT;
    uint256 constant internal RATES_ONE_HUNDRED_PCT   = 1000000021979553151239153027;


    /**********************/
    /*** Math Functions ***/
    /**********************/
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x);
    }
    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x);
    }
    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x);
    }
    function wmul(uint x, uint y) internal pure returns (uint z) {
        z = add(mul(x, y), WAD / 2) / WAD;
    }
    function rmul(uint x, uint y) internal pure returns (uint z) {
        z = add(mul(x, y), RAY / 2) / RAY;
    }
    function wdiv(uint x, uint y) internal pure returns (uint z) {
        z = add(mul(x, WAD), y / 2) / y;
    }
    function rdiv(uint x, uint y) internal pure returns (uint z) {
        z = add(mul(x, RAY), y / 2) / y;
    }

    /****************************/
    /*** Core Address Helpers ***/
    /****************************/
    function dai()        public view returns (address) { return getChangelogAddress("MCD_DAI"); }
    function mkr()        public view returns (address) { return getChangelogAddress("MCD_GOV"); }
    function vat()        public view returns (address) { return getChangelogAddress("MCD_VAT"); }
    function cat()        public view returns (address) { return getChangelogAddress("MCD_CAT"); }
    function jug()        public view returns (address) { return getChangelogAddress("MCD_JUG"); }
    function pot()        public view returns (address) { return getChangelogAddress("MCD_POT"); }
    function vow()        public view returns (address) { return getChangelogAddress("MCD_VOW"); }
    function end()        public view returns (address) { return getChangelogAddress("MCD_END"); }
    function reg()        public view returns (address) { return getChangelogAddress("ILK_REGISTRY"); }
    function spotter()    public view returns (address) { return getChangelogAddress("MCD_SPOT"); }
    function flap()       public view returns (address) { return getChangelogAddress("MCD_FLAP"); }
    function flop()       public view returns (address) { return getChangelogAddress("MCD_FLOP"); }
    function osmMom()     public view returns (address) { return getChangelogAddress("OSM_MOM"); }
    function govGuard()   public view returns (address) { return getChangelogAddress("GOV_GUARD"); }
    function flipperMom() public view returns (address) { return getChangelogAddress("FLIPPER_MOM"); }
    function pauseProxy() public view returns (address) { return getChangelogAddress("MCD_PAUSE_PROXY"); }
    function autoLine()   public view returns (address) { return getChangelogAddress("MCD_IAM_AUTO_LINE"); }
    function daiJoin()    public view returns (address) { return getChangelogAddress("MCD_JOIN_DAI"); }

    function flip(bytes32 ilk) public view returns (address _flip) {
        (,,,, _flip,,,) = RegistryLike(reg()).ilkData(ilk);
    }

    function getChangelogAddress(bytes32 key) public view returns (address) {
        return ChainlogLike(LOG).getAddress(key);
    }

    /****************************/
    /*** Changelog Management ***/
    /****************************/
    /**
        @dev Set an address in the MCD on-chain changelog.
        @param _key Access key for the address (e.g. "MCD_VAT")
        @param _val The address associated with the _key
    */
    function setChangelogAddress(bytes32 _key, address _val) public {
        ChainlogLike(LOG).setAddress(_key, _val);
    }

    /**
        @dev Set version in the MCD on-chain changelog.
        @param _version Changelog version (e.g. "1.1.2")
    */
    function setChangelogVersion(string memory _version) public {
        ChainlogLike(LOG).setVersion(_version);
    }
    /**
        @dev Set IPFS hash of IPFS changelog in MCD on-chain changelog.
        @param _ipfsHash IPFS hash (e.g. "QmefQMseb3AiTapiAKKexdKHig8wroKuZbmLtPLv4u2YwW")
    */
    function setChangelogIPFS(string memory _ipfsHash) public {
        ChainlogLike(LOG).setIPFS(_ipfsHash);
    }
    /**
        @dev Set SHA256 hash in MCD on-chain changelog.
        @param _SHA256Sum SHA256 hash (e.g. "e42dc9d043a57705f3f097099e6b2de4230bca9a020c797508da079f9079e35b")
    */
    function setChangelogSHA256(string memory _SHA256Sum) public {
        ChainlogLike(LOG).setSha256sum(_SHA256Sum);
    }


    /**********************/
    /*** Authorizations ***/
    /**********************/
    /**
        @dev Give an address authorization to perform auth actions on the contract.
        @param _base   The address of the contract where the authorization will be set
        @param _ward   Address to be authorized
    */
    function authorize(address _base, address _ward) public {
        Authorizable(_base).rely(_ward);
    }
    /**
        @dev Revoke contract authorization from an address.
        @param _base   The address of the contract where the authorization will be revoked
        @param _ward   Address to be deauthorized
    */
    function deauthorize(address _base, address _ward) public {
        Authorizable(_base).deny(_ward);
    }
    /**
        @dev Delegate vat authority to the specified address.
        @param _usr Address to be authorized
    */
    function delegateVat(address _usr) public {
        DssVat(vat()).hope(_usr);
    }
    /**
        @dev Revoke vat authority to the specified address.
        @param _usr Address to be deauthorized
    */
    function undelegateVat(address _usr) public {
        DssVat(vat()).nope(_usr);
    }

    /**************************/
    /*** Accumulating Rates ***/
    /**************************/
    /**
        @dev Update rate accumulation for the Dai Savings Rate (DSR).
    */
    function accumulateDSR() public {
        Drippable(pot()).drip();
    }
    /**
        @dev Update rate accumulation for the stability fees of a given collateral type.
        @param _ilk   Collateral type
    */
    function accumulateCollateralStabilityFees(bytes32 _ilk) public {
        Drippable(jug()).drip(_ilk);
    }

    /*********************/
    /*** Price Updates ***/
    /*********************/
    /**
        @dev Update price of a given collateral type.
        @param _ilk   Collateral type
    */
    function updateCollateralPrice(bytes32 _ilk) public {
        Pricing(spotter()).poke(_ilk);
    }

    /****************************/
    /*** System Configuration ***/
    /****************************/
    /**
        @dev Set a contract in another contract, defining the relationship (ex. set a new Cat contract in the Vat)
        @param _base   The address of the contract where the new contract address will be filed
        @param _what   Name of contract to file
        @param _addr   Address of contract to file
    */
    function setContract(address _base, bytes32 _what, address _addr) public {
        Fileable(_base).file(_what, _addr);
    }
    /**
        @dev Set a contract in another contract, defining the relationship (ex. set a new Cat contract in the Vat)
        @param _base   The address of the contract where the new contract address will be filed
        @param _ilk    Collateral type
        @param _what   Name of contract to file
        @param _addr   Address of contract to file
    */
    function setContract(address _base, bytes32 _ilk, bytes32 _what, address _addr) public {
        Fileable(_base).file(_ilk, _what, _addr);
    }

    /******************************/
    /*** System Risk Parameters ***/
    /******************************/
    // function setGlobalDebtCeiling(uint256 _amount) public { setGlobalDebtCeiling(vat(), _amount); }
    /**
        @dev Set the global debt ceiling. Amount will be converted to the correct internal precision.
        @param _amount The amount to set in DAI (ex. 10m DAI amount == 10000000)
    */
    function setGlobalDebtCeiling(uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-global-Line-precision"
        Fileable(vat()).file("Line", _amount * RAD);
    }
    /**
        @dev Increase the global debt ceiling by a specific amount. Amount will be converted to the correct internal precision.
        @param _amount The amount to add in DAI (ex. 10m DAI amount == 10000000)
    */
    function increaseGlobalDebtCeiling(uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-Line-increase-precision"
        address _vat = vat();
        Fileable(_vat).file("Line", add(DssVat(_vat).Line(), _amount * RAD));
    }
    /**
        @dev Decrease the global debt ceiling by a specific amount. Amount will be converted to the correct internal precision.
        @param _amount The amount to reduce in DAI (ex. 10m DAI amount == 10000000)
    */
    function decreaseGlobalDebtCeiling(uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-Line-decrease-precision"
        address _vat = vat();
        Fileable(_vat).file("Line", sub(DssVat(_vat).Line(), _amount * RAD));
    }
    /**
        @dev Set the Dai Savings Rate. See: docs/rates.txt
        @param _rate   The accumulated rate (ex. 4% => 1000000001243680656318820312)
    */
    function setDSR(uint256 _rate) public {
        require((_rate >= RAY) && (_rate <= RATES_ONE_HUNDRED_PCT));  // "LibDssExec/dsr-out-of-bounds"
        Fileable(pot()).file("dsr", _rate);
    }
    /**
        @dev Set the DAI amount for system surplus auctions. Amount will be converted to the correct internal precision.
        @param _amount The amount to set in DAI (ex. 10m DAI amount == 10000000)
    */
    function setSurplusAuctionAmount(uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-vow-bump-precision"
        Fileable(vow()).file("bump", _amount * RAD);
    }
    /**
        @dev Set the DAI amount for system surplus buffer, must be exceeded before surplus auctions start. Amount will be converted to the correct internal precision.
        @param _amount The amount to set in DAI (ex. 10m DAI amount == 10000000)
    */
    function setSurplusBuffer(uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-vow-hump-precision"
        Fileable(vow()).file("hump", _amount * RAD);
    }
    /**
        @dev Set minimum bid increase for surplus auctions. Amount will be converted to the correct internal precision.
        @dev Equation used for conversion is (1 + pct / 10,000) * WAD
        @param _pct_bps The pct, in basis points, to set in integer form (x100). (ex. 5% = 5 * 100 = 500)
    */
    function setMinSurplusAuctionBidIncrease(uint256 _pct_bps) public {
        require(_pct_bps < BPS_ONE_HUNDRED_PCT);  // "LibDssExec/incorrect-flap-beg-precision"
        Fileable(flap()).file("beg", add(WAD, wdiv(_pct_bps, BPS_ONE_HUNDRED_PCT)));
    }
    /**
        @dev Set bid duration for surplus auctions.
        @param _duration Amount of time for bids.
    */
    function setSurplusAuctionBidDuration(uint256 _duration) public {
        Fileable(flap()).file("ttl", _duration);
    }
    /**
        @dev Set total auction duration for surplus auctions.
        @param _duration Amount of time for auctions.
    */
    function setSurplusAuctionDuration(uint256 _duration) public {
        Fileable(flap()).file("tau", _duration);
    }
    /**
        @dev Set the number of seconds that pass before system debt is auctioned for MKR tokens.
        @param _duration Duration in seconds
    */
    function setDebtAuctionDelay(uint256 _duration) public {
        Fileable(vow()).file("wait", _duration);
    }
    /**
        @dev Set the DAI amount for system debt to be covered by each debt auction. Amount will be converted to the correct internal precision.
        @param _amount The amount to set in DAI (ex. 10m DAI amount == 10000000)
    */
    function setDebtAuctionDAIAmount(uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-vow-sump-precision"
        Fileable(vow()).file("sump", _amount * RAD);
    }
    /**
        @dev Set the starting MKR amount to be auctioned off to cover system debt in debt auctions. Amount will be converted to the correct internal precision.
        @param _amount The amount to set in MKR (ex. 250 MKR amount == 250)
    */
    function setDebtAuctionMKRAmount(uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-vow-dump-precision"
        Fileable(vow()).file("dump", _amount * WAD);
    }
    /**
        @dev Set minimum bid increase for debt auctions. Amount will be converted to the correct internal precision.
        @dev Equation used for conversion is (1 + pct / 10,000) * WAD
        @param _pct_bps    The pct, in basis points, to set in integer form (x100). (ex. 5% = 5 * 100 = 500)
    */
    function setMinDebtAuctionBidIncrease(uint256 _pct_bps) public {
        require(_pct_bps < BPS_ONE_HUNDRED_PCT);  // "LibDssExec/incorrect-flap-beg-precision"
        Fileable(flop()).file("beg", add(WAD, wdiv(_pct_bps, BPS_ONE_HUNDRED_PCT)));
    }
    /**
        @dev Set bid duration for debt auctions.
        @param _duration Amount of time for bids.
    */
    function setDebtAuctionBidDuration(uint256 _duration) public {
        Fileable(flop()).file("ttl", _duration);
    }
    /**
        @dev Set total auction duration for debt auctions.
        @param _duration Amount of time for auctions.
    */
    function setDebtAuctionDuration(uint256 _duration) public {
        Fileable(flop()).file("tau", _duration);
    }
    /**
        @dev Set the rate of increasing amount of MKR out for auction during debt auctions. Amount will be converted to the correct internal precision.
        @dev MKR amount is increased by this rate every "tick" (if auction duration has passed and no one has bid on the MKR)
        @dev Equation used for conversion is (1 + pct / 10,000) * WAD
        @param _pct_bps    The pct, in basis points, to set in integer form (x100). (ex. 5% = 5 * 100 = 500)
    */
    function setDebtAuctionMKRIncreaseRate(uint256 _pct_bps) public {
        Fileable(flop()).file("pad", add(WAD, wdiv(_pct_bps, BPS_ONE_HUNDRED_PCT)));
    }
    /**
        @dev Set the maximum total DAI amount that can be out for liquidation in the system at any point. Amount will be converted to the correct internal precision.
        @param _amount The amount to set in DAI (ex. 250,000 DAI amount == 250000)
    */
    function setMaxTotalDAILiquidationAmount(uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-vow-dump-precision"
        Fileable(cat()).file("box", _amount * RAD);
    }
    /**
        @dev Set the duration of time that has to pass during emergency shutdown before collateral can start being claimed by DAI holders.
        @param _duration Time in seconds to set for ES processing time
    */
    function setEmergencyShutdownProcessingTime(uint256 _duration) public {
        Fileable(end()).file("wait", _duration);
    }
    /**
        @dev Set the global stability fee (is not typically used, currently is 0).
            Many of the settings that change weekly rely on the rate accumulator
            described at https://docs.makerdao.com/smart-contract-modules/rates-module
            To check this yourself, use the following rate calculation (example 8%):

            $ bc -l <<< 'scale=27; e( l(1.08)/(60 * 60 * 24 * 365) )'

            A table of rates can also be found at:
            https://ipfs.io/ipfs/QmefQMseb3AiTapiAKKexdKHig8wroKuZbmLtPLv4u2YwW
        @param _rate   The accumulated rate (ex. 4% => 1000000001243680656318820312)
    */
    function setGlobalStabilityFee(uint256 _rate) public {
        require((_rate >= RAY) && (_rate <= RATES_ONE_HUNDRED_PCT));  // "LibDssExec/global-stability-fee-out-of-bounds"
        Fileable(jug()).file("base", _rate);
    }
    /**
        @dev Set the value of DAI in the reference asset (e.g. $1 per DAI). Value will be converted to the correct internal precision.
        @dev Equation used for conversion is value * RAY / 1000
        @param _value The value to set as integer (x1000) (ex. $1.025 == 1025)
    */
    function setDAIReferenceValue(uint256 _value) public {
        require(_value < WAD);  // "LibDssExec/incorrect-ilk-dunk-precision"
        Fileable(spotter()).file("par", rdiv(_value, 1000));
    }

    /*****************************/
    /*** Collateral Management ***/
    /*****************************/
    /**
        @dev Set a collateral debt ceiling. Amount will be converted to the correct internal precision.
        @param _ilk    The ilk to update (ex. bytes32("ETH-A"))
        @param _amount The amount to set in DAI (ex. 10m DAI amount == 10000000)
    */
    function setIlkDebtCeiling(bytes32 _ilk, uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-ilk-line-precision"
        Fileable(vat()).file(_ilk, "line", _amount * RAD);
    }
    /**
        @dev Increase a collateral debt ceiling. Amount will be converted to the correct internal precision.
        @param _ilk    The ilk to update (ex. bytes32("ETH-A"))
        @param _amount The amount to increase in DAI (ex. 10m DAI amount == 10000000)
        @param _global If true, increases the global debt ceiling by _amount
    */
    function increaseIlkDebtCeiling(bytes32 _ilk, uint256 _amount, bool _global) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-ilk-line-precision"
        address _vat = vat();
        (,,,uint256 line_,) = DssVat(_vat).ilks(_ilk);
        Fileable(_vat).file(_ilk, "line", add(line_, _amount * RAD));
        if (_global) { increaseGlobalDebtCeiling(_amount); }
    }
    /**
        @dev Decrease a collateral debt ceiling. Amount will be converted to the correct internal precision.
        @param _ilk    The ilk to update (ex. bytes32("ETH-A"))
        @param _amount The amount to decrease in DAI (ex. 10m DAI amount == 10000000)
        @param _global If true, decreases the global debt ceiling by _amount
    */
    function decreaseIlkDebtCeiling(bytes32 _ilk, uint256 _amount, bool _global) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-ilk-line-precision"
        address _vat = vat();
        (,,,uint256 line_,) = DssVat(_vat).ilks(_ilk);
        Fileable(_vat).file(_ilk, "line", sub(line_, _amount * RAD));
        if (_global) { decreaseGlobalDebtCeiling(_amount); }
    }
    /**
        @dev Set the parameters for an ilk in the "MCD_IAM_AUTO_LINE" auto-line
        @param _ilk    The ilk to update (ex. bytes32("ETH-A"))
        @param _amount The Maximum value (ex. 100m DAI amount == 100000000)
        @param _gap    The amount of Dai per step (ex. 5m Dai == 5000000)
        @param _ttl    The amount of time (in seconds)
    */
    function setIlkAutoLineParameters(bytes32 _ilk, uint256 _amount, uint256 _gap, uint256 _ttl) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-auto-line-amount-precision"
        require(_gap < WAD);  // "LibDssExec/incorrect-auto-line-gap-precision"
        IAMLike(autoLine()).setIlk(_ilk, _amount * RAD, _gap * RAD, _ttl);
    }
    /**
        @dev Set the debt ceiling for an ilk in the "MCD_IAM_AUTO_LINE" auto-line without updating the time values
        @param _ilk    The ilk to update (ex. bytes32("ETH-A"))
        @param _amount The amount to decrease in DAI (ex. 10m DAI amount == 10000000)
    */
    function setIlkAutoLineDebtCeiling(bytes32 _ilk, uint256 _amount) public {
        address _autoLine = autoLine();
        (, uint256 gap, uint48 ttl,,) = IAMLike(_autoLine).ilks(_ilk);
        require(gap != 0 && ttl != 0);  // "LibDssExec/auto-line-not-configured"
        IAMLike(_autoLine).setIlk(_ilk, _amount * RAD, uint256(gap), uint256(ttl));
    }
    /**
        @dev Remove an ilk in the "MCD_IAM_AUTO_LINE" auto-line
        @param _ilk    The ilk to remove (ex. bytes32("ETH-A"))
    */
    function removeIlkFromAutoLine(bytes32 _ilk) public {
        IAMLike(autoLine()).remIlk(_ilk);
    }
    /**
        @dev Set a collateral minimum vault amount. Amount will be converted to the correct internal precision.
        @param _ilk    The ilk to update (ex. bytes32("ETH-A"))
        @param _amount The amount to set in DAI (ex. 10m DAI amount == 10000000)
    */
    function setIlkMinVaultAmount(bytes32 _ilk, uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-ilk-dust-precision"
        Fileable(vat()).file(_ilk, "dust", _amount * RAD);
    }
    /**
        @dev Set a collateral liquidation penalty. Amount will be converted to the correct internal precision.
        @dev Equation used for conversion is (1 + pct / 10,000) * WAD
        @param _ilk    The ilk to update (ex. bytes32("ETH-A"))
        @param _pct_bps    The pct, in basis points, to set in integer form (x100). (ex. 10.25% = 10.25 * 100 = 1025)
    */
    function setIlkLiquidationPenalty(bytes32 _ilk, uint256 _pct_bps) public {
        require(_pct_bps < BPS_ONE_HUNDRED_PCT);  // "LibDssExec/incorrect-ilk-chop-precision"
        Fileable(cat()).file(_ilk, "chop", add(WAD, wdiv(_pct_bps, BPS_ONE_HUNDRED_PCT)));
    }
    /**
        @dev Set max DAI amount for liquidation per vault for collateral. Amount will be converted to the correct internal precision.
        @param _ilk    The ilk to update (ex. bytes32("ETH-A"))
        @param _amount The amount to set in DAI (ex. 10m DAI amount == 10000000)
    */
    function setIlkMaxLiquidationAmount(bytes32 _ilk, uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-ilk-dunk-precision"
        Fileable(cat()).file(_ilk, "dunk", _amount * RAD);
    }
    /**
        @dev Set a collateral liquidation ratio. Amount will be converted to the correct internal precision.
        @dev Equation used for conversion is pct * RAY / 10,000
        @param _ilk    The ilk to update (ex. bytes32("ETH-A"))
        @param _pct_bps    The pct, in basis points, to set in integer form (x100). (ex. 150% = 150 * 100 = 15000)
    */
    function setIlkLiquidationRatio(bytes32 _ilk, uint256 _pct_bps) public {
        require(_pct_bps < 10 * BPS_ONE_HUNDRED_PCT); // "LibDssExec/incorrect-ilk-mat-precision" // Fails if pct >= 1000%
        require(_pct_bps >= BPS_ONE_HUNDRED_PCT); // the liquidation ratio has to be bigger or equal to 100%
        Fileable(spotter()).file(_ilk, "mat", rdiv(_pct_bps, BPS_ONE_HUNDRED_PCT));
    }
    /**
        @dev Set minimum bid increase for collateral. Amount will be converted to the correct internal precision.
        @dev Equation used for conversion is (1 + pct / 10,000) * WAD
        @param _ilk   The ilk to update (ex. bytes32("ETH-A"))
        @param _pct_bps    The pct, in basis points, to set in integer form (x100). (ex. 5% = 5 * 100 = 500)
    */
    function setIlkMinAuctionBidIncrease(bytes32 _ilk, uint256 _pct_bps) public {
        require(_pct_bps < BPS_ONE_HUNDRED_PCT);  // "LibDssExec/incorrect-ilk-chop-precision"
        Fileable(flip(_ilk)).file("beg", add(WAD, wdiv(_pct_bps, BPS_ONE_HUNDRED_PCT)));
    }
    /**
        @dev Set bid duration for a collateral type.
        @param _ilk   The ilk to update (ex. bytes32("ETH-A"))
        @param _duration Amount of time for bids.
    */
    function setIlkBidDuration(bytes32 _ilk, uint256 _duration) public {
        Fileable(flip(_ilk)).file("ttl", _duration);
    }
    /**
        @dev Set auction duration for a collateral type.
        @param _ilk   The ilk to update (ex. bytes32("ETH-A"))
        @param _duration Amount of time for auctions.
    */
    function setIlkAuctionDuration(bytes32 _ilk, uint256 _duration) public {
        Fileable(flip(_ilk)).file("tau", _duration);
    }
    /**
        @dev Set the stability fee for a given ilk.
            Many of the settings that change weekly rely on the rate accumulator
            described at https://docs.makerdao.com/smart-contract-modules/rates-module
            To check this yourself, use the following rate calculation (example 8%):

            $ bc -l <<< 'scale=27; e( l(1.08)/(60 * 60 * 24 * 365) )'

            A table of rates can also be found at:
            https://ipfs.io/ipfs/QmefQMseb3AiTapiAKKexdKHig8wroKuZbmLtPLv4u2YwW

        @param _ilk    The ilk to update (ex. bytes32("ETH-A") )
        @param _rate   The accumulated rate (ex. 4% => 1000000001243680656318820312)
        @param _doDrip `true` to accumulate stability fees for the collateral
    */
    function setIlkStabilityFee(bytes32 _ilk, uint256 _rate, bool _doDrip) public {
        require((_rate >= RAY) && (_rate <= RATES_ONE_HUNDRED_PCT));  // "LibDssExec/ilk-stability-fee-out-of-bounds"
        address _jug = jug();
        if (_doDrip) Drippable(_jug).drip(_ilk);

        Fileable(_jug).file(_ilk, "duty", _rate);
    }


    /*************************/
    /*** Oracle Management ***/
    /*************************/
    /**
        @dev Adds oracle feeds to the Median's writer whitelist, allowing the feeds to write prices.
        @param _median Median core contract address
        @param _feeds      Array of oracle feed addresses to add to whitelist
    */
    function addWritersToMedianWhitelist(address _median, address[] memory _feeds) public {
        OracleLike_2(_median).lift(_feeds);
    }
    /**
        @dev Removes oracle feeds to the Median's writer whitelist, disallowing the feeds to write prices.
        @param _median Median core contract address
        @param _feeds      Array of oracle feed addresses to remove from whitelist
    */
    function removeWritersFromMedianWhitelist(address _median, address[] memory _feeds) public {
        OracleLike_2(_median).drop(_feeds);
    }
    /**
        @dev Adds addresses to the Median's reader whitelist, allowing the addresses to read prices from the median.
        @param _median Median core contract address
        @param _readers    Array of addresses to add to whitelist
    */
    function addReadersToMedianWhitelist(address _median, address[] memory _readers) public {
        OracleLike_2(_median).kiss(_readers);
    }
    /**
        @dev Adds an address to the Median's reader whitelist, allowing the address to read prices from the median.
        @param _median Median core contract address
        @param _reader     Address to add to whitelist
    */
    function addReaderToMedianWhitelist(address _median, address _reader) public {
        OracleLike_2(_median).kiss(_reader);
    }
    /**
        @dev Removes addresses from the Median's reader whitelist, disallowing the addresses to read prices from the median.
        @param _median Median core contract address
        @param _readers    Array of addresses to remove from whitelist
    */
    function removeReadersFromMedianWhitelist(address _median, address[] memory _readers) public {
        OracleLike_2(_median).diss(_readers);
    }
    /**
        @dev Removes an address to the Median's reader whitelist, disallowing the address to read prices from the median.
        @param _median Median core contract address
        @param _reader     Address to remove from whitelist
    */
    function removeReaderFromMedianWhitelist(address _median, address _reader) public {
        OracleLike_2(_median).diss(_reader);
    }
    /**
        @dev Sets the minimum number of valid messages from whitelisted oracle feeds needed to update median price.
        @param _median Median core contract address
        @param _minQuorum  Minimum number of valid messages from whitelisted oracle feeds needed to update median price (NOTE: MUST BE ODD NUMBER)
    */
    function setMedianWritersQuorum(address _median, uint256 _minQuorum) public {
        OracleLike_2(_median).setBar(_minQuorum);
    }
    /**
        @dev Adds an address to the Median's reader whitelist, allowing the address to read prices from the OSM.
        @param _osm        Oracle Security Module (OSM) core contract address
        @param _reader     Address to add to whitelist
    */
    function addReaderToOSMWhitelist(address _osm, address _reader) public {
        OracleLike_2(_osm).kiss(_reader);
    }
    /**
        @dev Removes an address to the Median's reader whitelist, disallowing the address to read prices from the OSM.
        @param _osm        Oracle Security Module (OSM) core contract address
        @param _reader     Address to remove from whitelist
    */
    function removeReaderFromOSMWhitelist(address _osm, address _reader) public {
        OracleLike_2(_osm).diss(_reader);
    }
    /**
        @dev Add OSM address to OSM mom, allowing it to be frozen by governance.
        @param _osm        Oracle Security Module (OSM) core contract address
        @param _ilk        Collateral type using OSM
    */
    function allowOSMFreeze(address _osm, bytes32 _ilk) public {
        MomLike(osmMom()).setOsm(_ilk, _osm);
    }


    /*****************************/
    /*** Collateral Onboarding ***/
    /*****************************/

    /**
        @dev Performs basic functions and sanity checks to add a new collateral type to the MCD system
        @param _ilk      Collateral type key code [Ex. "ETH-A"]
        @param _gem      Address of token contract
        @param _join     Address of join adapter
        @param _flip     Address of flipper
        @param _pip      Address of price feed
    */
    function addCollateralBase(
        bytes32 _ilk,
        address _gem,
        address _join,
        address _flip,
        address _pip
    ) public {
        // Sanity checks
        address _vat = vat();
        address _cat = cat();
        require(JoinLike(_join).vat() == _vat);     // "join-vat-not-match"
        require(JoinLike(_join).ilk() == _ilk);     // "join-ilk-not-match"
        require(JoinLike(_join).gem() == _gem);     // "join-gem-not-match"
        require(JoinLike(_join).dec() ==
                   ERC20(_gem).decimals());         // "join-dec-not-match"
        require(AuctionLike(_flip).vat() == _vat);  // "flip-vat-not-match"
        require(AuctionLike(_flip).cat() == _cat);  // "flip-cat-not-match"
        require(AuctionLike(_flip).ilk() == _ilk);  // "flip-ilk-not-match"

        // Set the token PIP in the Spotter
        setContract(spotter(), _ilk, "pip", _pip);

        // Set the ilk Flipper in the Cat
        setContract(_cat, _ilk, "flip", _flip);

        // Init ilk in Vat & Jug
        Initializable(_vat).init(_ilk);  // Vat
        Initializable(jug()).init(_ilk);  // Jug

        // Allow ilk Join to modify Vat registry
        authorize(_vat, _join);
		// Allow the ilk Flipper to reduce the Cat litterbox on deal()
        authorize(_cat, _flip);
        // Allow Cat to kick auctions in ilk Flipper
        authorize(_flip, _cat);
        // Allow End to yank auctions in ilk Flipper
        authorize(_flip, end());

        // Add new ilk to the IlkRegistry
        RegistryLike(reg()).add(_join);
    }


    /***************/
    /*** Payment ***/
    /***************/
    /**
        @dev Send a payment in ERC20 DAI from the surplus buffer.
        @param _target The target address to send the DAI to.
        @param _amount The amount to send in DAI (ex. 10m DAI amount == 10000000)
    */
    function sendPaymentFromSurplusBuffer(address _target, uint256 _amount) public {
        require(_amount < WAD);  // "LibDssExec/incorrect-ilk-line-precision"
        DssVat(vat()).suck(vow(), address(this), _amount * RAD);
        JoinLike(daiJoin()).exit(_target, _amount * WAD);
    }
}

////// lib/dss-exec-lib/src/DssAction.sol
//
// DssAction.sol -- DSS Executive Spell Actions
//
// Copyright (C) 2020 Maker Ecosystem Growth Holdings, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

/* pragma solidity ^0.6.11; */

/* import "./CollateralOpts.sol"; */
/* import { DssExecLib } from "./DssExecLib.sol"; */

interface OracleLike_1 {
    function src() external view returns (address);
}

abstract contract DssAction {

    using DssExecLib for *;

    // Office Hours defaults to true by default.
    //   To disable office hours, override this function and
    //    return false in the inherited action.
    function officeHours() public virtual returns (bool) {
        return true;
    }

    // DssExec calls execute. We limit this function subject to officeHours modifier.
    function execute() external limited {
        actions();
    }

    // DssAction developer must override `actions()` and place all actions to be called inside.
    //   The DssExec function will call this subject to the officeHours limiter
    //   By keeping this function public we allow simulations of `execute()` on the actions outside of the cast time.
    function actions() public virtual;

    // Modifier required to
    modifier limited {
        if (officeHours()) {
            uint day = (block.timestamp / 1 days + 3) % 7;
            require(day < 5, "Can only be cast on a weekday");
            uint hour = block.timestamp / 1 hours % 24;
            require(hour >= 14 && hour < 21, "Outside office hours");
        }
        _;
    }

    /*****************************/
    /*** Collateral Onboarding ***/
    /*****************************/

    // Complete collateral onboarding logic.
    function addNewCollateral(CollateralOpts memory co) internal {
        // Add the collateral to the system.
        DssExecLib.addCollateralBase(co.ilk, co.gem, co.join, co.flip, co.pip);

        // Allow FlipperMom to access to the ilk Flipper
        address _flipperMom = DssExecLib.flipperMom();
        DssExecLib.authorize(co.flip, _flipperMom);
        // Disallow Cat to kick auctions in ilk Flipper
        if(!co.isLiquidatable) { DssExecLib.deauthorize(_flipperMom, co.flip); }

        if(co.isOSM) { // If pip == OSM
            // Allow OsmMom to access to the TOKEN OSM
            DssExecLib.authorize(co.pip, DssExecLib.osmMom());
            if (co.whitelistOSM) { // If median is src in OSM
                // Whitelist OSM to read the Median data (only necessary if it is the first time the token is being added to an ilk)
                DssExecLib.addReaderToMedianWhitelist(address(OracleLike_1(co.pip).src()), co.pip);
            }
            // Whitelist Spotter to read the OSM data (only necessary if it is the first time the token is being added to an ilk)
            DssExecLib.addReaderToOSMWhitelist(co.pip, DssExecLib.spotter());
            // Whitelist End to read the OSM data (only necessary if it is the first time the token is being added to an ilk)
            DssExecLib.addReaderToOSMWhitelist(co.pip, DssExecLib.end());
            // Set TOKEN OSM in the OsmMom for new ilk
            DssExecLib.allowOSMFreeze(co.pip, co.ilk);
        }
        // Increase the global debt ceiling by the ilk ceiling
        DssExecLib.increaseGlobalDebtCeiling(co.ilkDebtCeiling);
        // Set the ilk debt ceiling
        DssExecLib.setIlkDebtCeiling(co.ilk, co.ilkDebtCeiling);
        // Set the ilk dust
        DssExecLib.setIlkMinVaultAmount(co.ilk, co.minVaultAmount);
        // Set the dunk size
        DssExecLib.setIlkMaxLiquidationAmount(co.ilk, co.maxLiquidationAmount);
        // Set the ilk liquidation penalty
        DssExecLib.setIlkLiquidationPenalty(co.ilk, co.liquidationPenalty);

        // Set the ilk stability fee
        DssExecLib.setIlkStabilityFee(co.ilk, co.ilkStabilityFee, true);

        // Set the ilk percentage between bids
        DssExecLib.setIlkMinAuctionBidIncrease(co.ilk, co.bidIncrease);
        // Set the ilk time max time between bids
        DssExecLib.setIlkBidDuration(co.ilk, co.bidDuration);
        // Set the ilk max auction duration
        DssExecLib.setIlkAuctionDuration(co.ilk, co.auctionDuration);
        // Set the ilk min collateralization ratio
        DssExecLib.setIlkLiquidationRatio(co.ilk, co.liquidationRatio);

        // Update ilk spot value in Vat
        DssExecLib.updateCollateralPrice(co.ilk);
    }
}

////// lib/dss-exec-lib/src/DssExec.sol
//
// DssExec.sol -- MakerDAO Executive Spell Template
//
// Copyright (C) 2020 Maker Ecosystem Growth Holdings, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

/* pragma solidity ^0.6.11; */

interface PauseAbstract {
    function delay() external view returns (uint256);
    function plot(address, bytes32, bytes calldata, uint256) external;
    function exec(address, bytes32, bytes calldata, uint256) external returns (bytes memory);
}

interface Changelog {
    function getAddress(bytes32) external view returns (address);
}

interface SpellAction {
    function officeHours() external view returns (bool);
}

contract DssExec {

    Changelog      constant public log   = Changelog(0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F);
    uint256                 public eta;
    bytes                   public sig;
    bool                    public done;
    bytes32       immutable public tag;
    address       immutable public action;
    uint256       immutable public expiration;
    PauseAbstract immutable public pause;

    // Provides a descriptive tag for bot consumption
    // This should be modified weekly to provide a summary of the actions
    // Hash: seth keccak -- "$(wget https://<executive-vote-canonical-post> -q -O - 2>/dev/null)"
    string                  public description;

    function officeHours() external view returns (bool) {
        return SpellAction(action).officeHours();
    }

    function nextCastTime() external view returns (uint256 castTime) {
        require(eta != 0, "DssExec/spell-not-scheduled");
        castTime = block.timestamp > eta ? block.timestamp : eta; // Any day at XX:YY

        if (SpellAction(action).officeHours()) {
            uint256 day    = (castTime / 1 days + 3) % 7;
            uint256 hour   = castTime / 1 hours % 24;
            uint256 minute = castTime / 1 minutes % 60;
            uint256 second = castTime % 60;

            if (day >= 5) {
                castTime += (6 - day) * 1 days;                 // Go to Sunday XX:YY
                castTime += (24 - hour + 14) * 1 hours;         // Go to 14:YY UTC Monday
                castTime -= minute * 1 minutes + second;        // Go to 14:00 UTC
            } else {
                if (hour >= 21) {
                    if (day == 4) castTime += 2 days;           // If Friday, fast forward to Sunday XX:YY
                    castTime += (24 - hour + 14) * 1 hours;     // Go to 14:YY UTC next day
                    castTime -= minute * 1 minutes + second;    // Go to 14:00 UTC
                } else if (hour < 14) {
                    castTime += (14 - hour) * 1 hours;          // Go to 14:YY UTC same day
                    castTime -= minute * 1 minutes + second;    // Go to 14:00 UTC
                }
            }
        }
    }

    // @param _description  A string description of the spell
    // @param _expiration   The timestamp this spell will expire. (Ex. now + 30 days)
    // @param _spellAction  The address of the spell action
    constructor(string memory _description, uint256 _expiration, address _spellAction) public {
        pause       = PauseAbstract(log.getAddress("MCD_PAUSE"));
        description = _description;
        expiration  = _expiration;
        action      = _spellAction;

        sig = abi.encodeWithSignature("execute()");
        bytes32 _tag;                    // Required for assembly access
        address _action = _spellAction;  // Required for assembly access
        assembly { _tag := extcodehash(_action) }
        tag = _tag;
    }

    function schedule() public {
        require(now <= expiration, "This contract has expired");
        require(eta == 0, "This spell has already been scheduled");
        eta = now + PauseAbstract(pause).delay();
        pause.plot(action, tag, sig, eta);
    }

    function cast() public {
        require(!done, "spell-already-cast");
        done = true;
        pause.exec(action, tag, sig, eta);
    }
}

////// lib/dss-interfaces/src/dss/OsmAbstract.sol
/* pragma solidity >=0.5.12; */

// https://github.com/makerdao/osm
interface OsmAbstract {
    function wards(address) external view returns (uint256);
    function rely(address) external;
    function deny(address) external;
    function stopped() external view returns (uint256);
    function src() external view returns (address);
    function hop() external view returns (uint16);
    function zzz() external view returns (uint64);
    function cur() external view returns (uint128, uint128);
    function nxt() external view returns (uint128, uint128);
    function bud(address) external view returns (uint256);
    function stop() external;
    function start() external;
    function change(address) external;
    function step(uint16) external;
    function void() external;
    function pass() external view returns (bool);
    function poke() external;
    function peek() external view returns (bytes32, bool);
    function peep() external view returns (bytes32, bool);
    function read() external view returns (bytes32);
    function kiss(address) external;
    function diss(address) external;
    function kiss(address[] calldata) external;
    function diss(address[] calldata) external;
}

////// lib/dss-interfaces/src/dss/PotAbstract.sol
/* pragma solidity >=0.5.12; */

// https://github.com/makerdao/dss/blob/master/src/pot.sol
interface PotAbstract {
    function wards(address) external view returns (uint256);
    function rely(address) external;
    function deny(address) external;
    function pie(address) external view returns (uint256);
    function Pie() external view returns (uint256);
    function dsr() external view returns (uint256);
    function chi() external view returns (uint256);
    function vat() external view returns (address);
    function vow() external view returns (address);
    function rho() external view returns (uint256);
    function live() external view returns (uint256);
    function file(bytes32, uint256) external;
    function file(bytes32, address) external;
    function cage() external;
    function drip() external returns (uint256);
    function join(uint256) external;
    function exit(uint256) external;
}

////// lib/dss-interfaces/src/dss/VatAbstract.sol
/* pragma solidity >=0.5.12; */

// https://github.com/makerdao/dss/blob/master/src/vat.sol
interface VatAbstract {
    function wards(address) external view returns (uint256);
    function rely(address) external;
    function deny(address) external;
    function can(address, address) external view returns (uint256);
    function hope(address) external;
    function nope(address) external;
    function ilks(bytes32) external view returns (uint256, uint256, uint256, uint256, uint256);
    function urns(bytes32, address) external view returns (uint256, uint256);
    function gem(bytes32, address) external view returns (uint256);
    function dai(address) external view returns (uint256);
    function sin(address) external view returns (uint256);
    function debt() external view returns (uint256);
    function vice() external view returns (uint256);
    function Line() external view returns (uint256);
    function live() external view returns (uint256);
    function init(bytes32) external;
    function file(bytes32, uint256) external;
    function file(bytes32, bytes32, uint256) external;
    function cage() external;
    function slip(bytes32, address, int256) external;
    function flux(bytes32, address, address, uint256) external;
    function move(address, address, uint256) external;
    function frob(bytes32, address, address, address, int256, int256) external;
    function fork(bytes32, address, address, int256, int256) external;
    function grab(bytes32, address, address, address, int256, int256) external;
    function heal(uint256) external;
    function suck(address, address, uint256) external;
    function fold(bytes32, address, int256) external;
}

////// src/DssSpell.sol
// Copyright (C) 2021 Maker Ecosystem Growth Holdings, INC.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
/* pragma solidity 0.6.11; */

/* import "dss-exec-lib/DssExec.sol"; */
/* import "dss-exec-lib/DssAction.sol"; */
/* import "lib/dss-interfaces/src/dss/OsmAbstract.sol"; */
/* import "lib/dss-interfaces/src/dss/PotAbstract.sol"; */
/* import "lib/dss-interfaces/src/dss/VatAbstract.sol"; */

interface ChainlogAbstract_2 {
    function removeAddress(bytes32) external;
}

interface LPOracle {
    function orb0() external view returns (address);
    function orb1() external view returns (address);
}

interface GnosisAllowanceModule {
    function executeAllowanceTransfer(address safe, address token, address to, uint96 amount, address paymentToken, uint96 payment, address delegate, bytes memory signature) external;
}

contract DssSpellAction is DssAction {

    // Provides a descriptive tag for bot consumption
    // This should be modified weekly to provide a summary of the actions
    // Hash: seth keccak -- "$(wget https://raw.githubusercontent.com/makerdao/community/00fc3831345790536ad792b29da2c3cb9d6cbad3/governance/votes/Executive%20vote%20-%20February%2019%2C%202021.md -q -O - 2>/dev/null)"
    string public constant description =
        "2021-02-19 MakerDAO Executive Spell | Hash: 0xedcf17520223556b12c535abe7dfc8c70f4f98d4423119a05a37b92b18048bca";


    // Many of the settings that change weekly rely on the rate accumulator
    // described at https://docs.makerdao.com/smart-contract-modules/rates-module
    // To check this yourself, use the following rate calculation (example 8%):
    //
    // $ bc -l <<< 'scale=27; e( l(1.08)/(60 * 60 * 24 * 365) )'
    //
    // A table of rates can be found at
    //    https://ipfs.io/ipfs/QmefQMseb3AiTapiAKKexdKHig8wroKuZbmLtPLv4u2YwW
    //
    uint256 constant ONE_HUNDREDTH_PCT  = 1000000000003170820659990704;
    uint256 constant THREE_PCT          = 1000000000937303470807876289;
    uint256 constant FOUR_PCT           = 1000000001243680656318820312;

    uint256 constant WAD        = 10**18;
    uint256 constant RAD        = 10**45;
    uint256 constant MILLION    = 10**6;

    address constant UNIV2WBTCDAI_GEM   = 0x231B7589426Ffe1b75405526fC32aC09D44364c4;
    address constant UNIV2WBTCDAI_JOIN  = 0xD40798267795Cbf3aeEA8E9F8DCbdBA9b5281fcC;
    address constant UNIV2WBTCDAI_FLIP  = 0x172200d12D09C2698Dd918d347155fE6692f5662;
    address constant UNIV2WBTCDAI_PIP   = 0x5FB5a346347ACf4FCD3AAb28f5eE518785FB0AD0;

    address constant UNIV2AAVEETH_GEM   = 0xDFC14d2Af169B0D36C4EFF567Ada9b2E0CAE044f;
    address constant UNIV2AAVEETH_JOIN  = 0x42AFd448Df7d96291551f1eFE1A590101afB1DfF;
    address constant UNIV2AAVEETH_FLIP  = 0x20D298ca96bf8c2000203B911908DbDc1a8Bac58;
    address constant UNIV2AAVEETH_PIP   = 0x8D34DC2c33A6386E96cA562D8478Eaf82305b81a;

    function actions() public override {
        // Increase ETH-A Maximum Debt Ceiling
        DssExecLib.setIlkAutoLineDebtCeiling("ETH-A", 2_500 * MILLION);

        // Set Debt Ceiling Instant Access Module Parameters For Multiple Vault Types
        DssExecLib.setIlkAutoLineParameters("LRC-A", 10 * MILLION, 2 * MILLION, 12 hours);
        DssExecLib.setIlkAutoLineParameters("BAT-A", 3 * MILLION, 1 * MILLION, 12 hours);
        DssExecLib.setIlkAutoLineParameters("BAL-A", 5 * MILLION, 1 * MILLION, 12 hours);
        DssExecLib.setIlkAutoLineParameters("MANA-A", 2 * MILLION, 500_000, 12 hours);
        DssExecLib.setIlkAutoLineParameters("ZRX-A", 5 * MILLION, 1 * MILLION, 12 hours);
        DssExecLib.setIlkAutoLineParameters("KNC-A", 5 * MILLION, 1 * MILLION, 12 hours);
        DssExecLib.setIlkAutoLineParameters("RENBTC-A", 2 * MILLION, 500_000, 12 hours);

        // Increase System Surplus Buffer
        DssExecLib.setSurplusBuffer(30 * MILLION);

        // Onboard UNIV2WBTCDAI-A
        DssExecLib.addReaderToMedianWhitelist(
            LPOracle(UNIV2WBTCDAI_PIP).orb0(),
            UNIV2WBTCDAI_PIP
        );
        CollateralOpts memory UNIV2WBTCDAI_A = CollateralOpts({
            ilk: "UNIV2WBTCDAI-A",
            gem: UNIV2WBTCDAI_GEM,
            join: UNIV2WBTCDAI_JOIN,
            flip: UNIV2WBTCDAI_FLIP,
            pip: UNIV2WBTCDAI_PIP,
            isLiquidatable: true,
            isOSM: true,
            whitelistOSM: false,
            ilkDebtCeiling: 3 * MILLION,
            minVaultAmount: 2000,
            maxLiquidationAmount: 50000,
            liquidationPenalty: 1300,
            ilkStabilityFee: THREE_PCT,
            bidIncrease: 300,
            bidDuration: 6 hours,
            auctionDuration: 6 hours,
            liquidationRatio: 12500
        });
        addNewCollateral(UNIV2WBTCDAI_A);
        DssExecLib.setChangelogAddress("UNIV2WBTCDAI",             UNIV2WBTCDAI_GEM);
        DssExecLib.setChangelogAddress("MCD_JOIN_UNIV2WBTCDAI_A",  UNIV2WBTCDAI_JOIN);
        DssExecLib.setChangelogAddress("MCD_FLIP_UNIV2WBTCDAI_A",  UNIV2WBTCDAI_FLIP);
        DssExecLib.setChangelogAddress("PIP_UNIV2WBTCDAI",         UNIV2WBTCDAI_PIP);

        // Onboard UNIV2AAVEETH-A
        DssExecLib.addReaderToMedianWhitelist(
            LPOracle(UNIV2AAVEETH_PIP).orb0(),
            UNIV2AAVEETH_PIP
        );
        DssExecLib.addReaderToMedianWhitelist(
            LPOracle(UNIV2AAVEETH_PIP).orb1(),
            UNIV2AAVEETH_PIP
        );
        CollateralOpts memory UNIV2AAVEETH_A = CollateralOpts({
            ilk: "UNIV2AAVEETH-A",
            gem: UNIV2AAVEETH_GEM,
            join: UNIV2AAVEETH_JOIN,
            flip: UNIV2AAVEETH_FLIP,
            pip: UNIV2AAVEETH_PIP,
            isLiquidatable: true,
            isOSM: true,
            whitelistOSM: false,
            ilkDebtCeiling: 3 * MILLION,
            minVaultAmount: 2000,
            maxLiquidationAmount: 50000,
            liquidationPenalty: 1300,
            ilkStabilityFee: FOUR_PCT,
            bidIncrease: 300,
            bidDuration: 6 hours,
            auctionDuration: 6 hours,
            liquidationRatio: 16500
        });
        addNewCollateral(UNIV2AAVEETH_A);
        DssExecLib.setChangelogAddress("UNIV2AAVEETH",             UNIV2AAVEETH_GEM);
        DssExecLib.setChangelogAddress("MCD_JOIN_UNIV2AAVEETH_A",  UNIV2AAVEETH_JOIN);
        DssExecLib.setChangelogAddress("MCD_FLIP_UNIV2AAVEETH_A",  UNIV2AAVEETH_FLIP);
        DssExecLib.setChangelogAddress("PIP_UNIV2AAVEETH",         UNIV2AAVEETH_PIP);

        // Dai Savings Rate Adjustment
        PotAbstract(DssExecLib.pot()).drip();
        DssExecLib.setDSR(ONE_HUNDREDTH_PCT);

        // Remove Permissions for Liquidations Circuit Breaker
        address flipperMom = DssExecLib.flipperMom();
        DssExecLib.deauthorize(DssExecLib.flip("PSM-USDC-A"), flipperMom);
        DssExecLib.deauthorize(DssExecLib.flip("UNIV2DAIUSDC-A"), flipperMom);

        // Fix for Line != sum lines rounding error issue (0.602857457497899800874246318932698818152722680 DAI)
        VatAbstract vat = VatAbstract(DssExecLib.vat());
        vat.file("Line", vat.Line() + 602857457497899800874246318932698818152722680);

        // bump Changelog version
        DssExecLib.setChangelogVersion("1.2.7");
    }
}

contract DssSpell is DssExec {
    DssSpellAction internal action_ = new DssSpellAction();
    constructor() DssExec(action_.description(), block.timestamp + 30 days, address(action_)) public {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"action","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cast","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"done","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"expiration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"log","outputs":[{"internalType":"contract Changelog","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextCastTime","outputs":[{"internalType":"uint256","name":"castTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"officeHours","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[{"internalType":"contract PauseAbstract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"schedule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tag","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]

6101006040526040516200001390620002ca565b604051809103906000f08015801562000030573d6000803e3d6000fd5b50600480546001600160a01b0319166001600160a01b03929092169190911790553480156200005e57600080fd5b506004805460408051633942720b60e11b815290516001600160a01b0390921692637284e416928282019260009290829003018186803b158015620000a257600080fd5b505afa158015620000b7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015620000e157600080fd5b81019080805160405193929190846401000000008211156200010257600080fd5b9083019060208201858111156200011857600080fd5b82516401000000008111828201881017156200013357600080fd5b82525081516020918201929091019080838360005b838110156200016257818101518382015260200162000148565b50505050905090810190601f168015620001905780820380516001836020036101000a031916815260200191505b506040525050504262278d0001600460009054906101000a90046001600160a01b031673da0ab1e0017debcd72be8599041a2aa3ba7e740f6001600160a01b03166321f8a7216040518163ffffffff1660e01b81526004018080684d43445f504155534560b81b815250602001905060206040518083038186803b1580156200021857600080fd5b505afa1580156200022d573d6000803e3d6000fd5b505050506040513d60208110156200024457600080fd5b505160601b6001600160601b03191660e05282516200026b906003906020860190620002d8565b5060c08290526001600160601b0319606082901b1660a0526040805160048152602481019091526020810180516001600160e01b0316631851865560e21b1781529051620002bc91600191620002d8565b503f608052506200037d9050565b6123978062000f3183390190565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200031b57805160ff19168380011785556200034b565b828001600101855582156200034b579182015b828111156200034b5782518255916020019190600101906200032e565b50620003599291506200035d565b5090565b6200037a91905b8082111562000359576000815560010162000364565b90565b60805160a05160601c60c05160e05160601c610b46620003eb600039806103ef5280610504528061075b528061087c5250806102a752806106a75250806102835280610309528061047f52806107fc52806109b25250806102e352806104b252806108275250610b466000f3fe608060405234801561001057600080fd5b50600436106100ce5760003560e01c80637284e4161161008c578063ae8421e111610066578063ae8421e1146101d4578063b0604a26146101dc578063f7992d85146101e4578063fe7d47bb146101ec576100ce565b80637284e416146101ba5780638456cb59146101c257806396d373e5146101ca576100ce565b8062a7029b146100d35780630a7a1c4d146101505780634665096d1461017457806351973ec91461018e57806351f91066146101965780636e832f071461019e575b600080fd5b6100db6101f4565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610158610281565b604080516001600160a01b039092168252519081900360200190f35b61017c6102a5565b60408051918252519081900360200190f35b6101586102c9565b61017c6102e1565b6101a6610305565b604080519115158252519081900360200190f35b6100db610392565b6101586103ed565b6101d2610411565b005b6101a661069c565b6101d26106a5565b61017c610940565b61017c610946565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156102795780601f1061024e57610100808354040283529160200191610279565b820191906000526020600020905b81548152906001019060200180831161025c57829003601f168201915b505050505081565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b73da0ab1e0017debcd72be8599041a2aa3ba7e740f81565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e832f076040518163ffffffff1660e01b815260040160206040518083038186803b15801561036057600080fd5b505afa158015610374573d6000803e3d6000fd5b505050506040513d602081101561038a57600080fd5b505190505b90565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156102795780601f1061024e57610100808354040283529160200191610279565b7f000000000000000000000000000000000000000000000000000000000000000081565b60025460ff161561045e576040805162461bcd60e51b81526020600482015260126024820152711cdc195b1b0b585b1c9958591e4b58d85cdd60721b604482015290519081900360640190fd5b6002805460ff19166001908117825560005460405163168ccd6760e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03818116600484019081527f000000000000000000000000000000000000000000000000000000000000000060248501819052606485018690526080604486019081528754600019818a161561010002011698909804608486018190527f0000000000000000000000000000000000000000000000000000000000000000939093169763168ccd6797949691959193909160a40190859080156105895780601f1061055e57610100808354040283529160200191610589565b820191906000526020600020905b81548152906001019060200180831161056c57829003601f168201915b505095505050505050600060405180830381600087803b1580156105ac57600080fd5b505af11580156105c0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156105e957600080fd5b810190808051604051939291908464010000000082111561060957600080fd5b90830190602082018581111561061e57600080fd5b825164010000000081118282018810171561063857600080fd5b82525081516020918201929091019080838360005b8381101561066557818101518382015260200161064d565b50505050905090810190601f1680156106925780820380516001836020036101000a031916815260200191505b5060405250505050565b60025460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000042111561071a576040805162461bcd60e51b815260206004820152601960248201527f5468697320636f6e747261637420686173206578706972656400000000000000604482015290519081900360640190fd5b600054156107595760405162461bcd60e51b8152600401808060200182810382526025815260200180610aec6025913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636a42b8f86040518163ffffffff1660e01b815260040160206040518083038186803b1580156107b257600080fd5b505afa1580156107c6573d6000803e3d6000fd5b505050506040513d60208110156107dc57600080fd5b5051420160008190556040516346d2fbbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000818116600484019081527f0000000000000000000000000000000000000000000000000000000000000000602485018190526064850186905260806044860190815260018054600281831615610100026000190190911604608488018190527f0000000000000000000000000000000000000000000000000000000000000000909616976346d2fbbb97959693959194909390929160a40190859080156109035780601f106108d857610100808354040283529160200191610903565b820191906000526020600020905b8154815290600101906020018083116108e657829003601f168201915b505095505050505050600060405180830381600087803b15801561092657600080fd5b505af115801561093a573d6000803e3d6000fd5b50505050565b60005481565b6000805461099b576040805162461bcd60e51b815260206004820152601b60248201527f447373457865632f7370656c6c2d6e6f742d7363686564756c65640000000000604482015290519081900360640190fd5b60005442116109ac576000546109ae565b425b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e832f076040518163ffffffff1660e01b815260040160206040518083038186803b158015610a0957600080fd5b505afa158015610a1d573d6000803e3d6000fd5b505050506040513d6020811015610a3357600080fd5b50511561038f576007620151808204600301066018610e10830406603c80840481900690840660058410610a8c578360060362015180028501945082601803600e01610e1002850194508082603c020185039450610ae4565b60158310610ac4578360041415610aa6576202a300850194505b82601803600e01610e1002850194508082603c020185039450610ae4565b600e831015610ae45782600e03610e1002850194508082603c0201850394505b505050509056fe54686973207370656c6c2068617320616c7265616479206265656e207363686564756c6564a264697066735822122007ec378bac69f35a095b7a77f83ed10fece1cf296a02ada626aa1f31a92fb35c64736f6c634300060b0033608060405234801561001057600080fd5b50612377806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806361461954146100515780636e832f071461005b5780637284e41614610077578063f99e36bc146100f4575b600080fd5b6100596100fc565b005b6100636101d8565b604080519115158252519081900360200190f35b61007f6101dd565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100b95781810151838201526020016100a1565b50505050905090810190601f1680156100e65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100596101f9565b6101046101d8565b156101ce576007620151804204600301066005811061016a576040805162461bcd60e51b815260206004820152601d60248201527f43616e206f6e6c792062652063617374206f6e2061207765656b646179000000604482015290519081900360640190fd5b6018610e10420406600e81108015906101835750601581105b6101cb576040805162461bcd60e51b81526020600482015260146024820152734f757473696465206f666669636520686f75727360601b604482015290519081900360640190fd5b50505b6101d66101f9565b565b600190565b6040518060a00160405280606e81526020016122d4606e913981565b604080516313f6ee8960e11b8152644554482d4160d81b6004820152639502f90060248201529051739a6c490ba30507e732d61235eff94c26aea234ef916327eddd12916044808301926000929190829003018186803b15801561025c57600080fd5b505af4158015610270573d6000803e3d6000fd5b50506040805163b085f23760e01b8152644c52432d4160d81b6004820152629896806024820152621e8480604482015261a8c060648201529051739a6c490ba30507e732d61235eff94c26aea234ef935063b085f23792506084808301926000929190829003018186803b1580156102e757600080fd5b505af41580156102fb573d6000803e3d6000fd5b50506040805163b085f23760e01b8152644241542d4160d81b6004820152622dc6c06024820152620f4240604482015261a8c060648201529051739a6c490ba30507e732d61235eff94c26aea234ef935063b085f23792506084808301926000929190829003018186803b15801561037257600080fd5b505af4158015610386573d6000803e3d6000fd5b50506040805163b085f23760e01b81526442414c2d4160d81b6004820152624c4b406024820152620f4240604482015261a8c060648201529051739a6c490ba30507e732d61235eff94c26aea234ef935063b085f23792506084808301926000929190829003018186803b1580156103fd57600080fd5b505af4158015610411573d6000803e3d6000fd5b50506040805163b085f23760e01b8152654d414e412d4160d01b6004820152621e848060248201526207a120604482015261a8c060648201529051739a6c490ba30507e732d61235eff94c26aea234ef935063b085f23792506084808301926000929190829003018186803b15801561048957600080fd5b505af415801561049d573d6000803e3d6000fd5b50506040805163b085f23760e01b8152645a52582d4160d81b6004820152624c4b406024820152620f4240604482015261a8c060648201529051739a6c490ba30507e732d61235eff94c26aea234ef935063b085f23792506084808301926000929190829003018186803b15801561051457600080fd5b505af4158015610528573d6000803e3d6000fd5b50506040805163b085f23760e01b8152644b4e432d4160d81b6004820152624c4b406024820152620f4240604482015261a8c060648201529051739a6c490ba30507e732d61235eff94c26aea234ef935063b085f23792506084808301926000929190829003018186803b15801561059f57600080fd5b505af41580156105b3573d6000803e3d6000fd5b50506040805163b085f23760e01b81526752454e4254432d4160c01b6004820152621e848060248201526207a120604482015261a8c060648201529051739a6c490ba30507e732d61235eff94c26aea234ef935063b085f23792506084808301926000929190829003018186803b15801561062d57600080fd5b505af4158015610641573d6000803e3d6000fd5b505060408051639f476ee160e01b81526301c9c38060048201529051739a6c490ba30507e732d61235eff94c26aea234ef9350639f476ee192506024808301926000929190829003018186803b15801561069a57600080fd5b505af41580156106ae573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef63998745aa735fb5a346347acf4fcd3aab28f5ee518785fb0ad06001600160a01b0316636c2552f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561071957600080fd5b505afa15801561072d573d6000803e3d6000fd5b505050506040513d602081101561074357600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152735fb5a346347acf4fcd3aab28f5ee518785fb0ad06024830152516044808301926000929190829003018186803b1580156107a457600080fd5b505af41580156107b8573d6000803e3d6000fd5b505050506107c4612222565b5060408051610220810182526d554e495632574254434441492d4160901b815273231b7589426ffe1b75405526fc32ac09d44364c4602082015273d40798267795cbf3aeea8e9f8dcbdba9b5281fcc9181019190915273172200d12d09c2698dd918d347155fe6692f56626060820152735fb5a346347acf4fcd3aab28f5ee518785fb0ad06080820152600160a0820181905260c0820152600060e0820152622dc6c06101008201526107d061012082015261c3506101408201526105146101608201526b033b2e3cacd278c7503e82c161018082015261012c6101a08201526154606101c082018190526101e08201526130d46102008201526108c781611675565b604080516319d900a160e01b81526b554e4956325742544344414960a01b600482015273231b7589426ffe1b75405526fc32ac09d44364c460248201529051739a6c490ba30507e732d61235eff94c26aea234ef916319d900a1916044808301926000929190829003018186803b15801561094157600080fd5b505af4158015610955573d6000803e3d6000fd5b5050604080516319d900a160e01b81527f4d43445f4a4f494e5f554e495632574254434441495f41000000000000000000600482015273d40798267795cbf3aeea8e9f8dcbdba9b5281fcc60248201529051739a6c490ba30507e732d61235eff94c26aea234ef93506319d900a192506044808301926000929190829003018186803b1580156109e457600080fd5b505af41580156109f8573d6000803e3d6000fd5b5050604080516319d900a160e01b81527f4d43445f464c49505f554e495632574254434441495f41000000000000000000600482015273172200d12d09c2698dd918d347155fe6692f566260248201529051739a6c490ba30507e732d61235eff94c26aea234ef93506319d900a192506044808301926000929190829003018186803b158015610a8757600080fd5b505af4158015610a9b573d6000803e3d6000fd5b5050604080516319d900a160e01b81526f5049505f554e4956325742544344414960801b6004820152735fb5a346347acf4fcd3aab28f5ee518785fb0ad060248201529051739a6c490ba30507e732d61235eff94c26aea234ef93506319d900a192506044808301926000929190829003018186803b158015610b1d57600080fd5b505af4158015610b31573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef63998745aa738d34dc2c33a6386e96ca562d8478eaf82305b81a6001600160a01b0316636c2552f96040518163ffffffff1660e01b815260040160206040518083038186803b158015610b9c57600080fd5b505afa158015610bb0573d6000803e3d6000fd5b505050506040513d6020811015610bc657600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152738d34dc2c33a6386e96ca562d8478eaf82305b81a6024830152516044808301926000929190829003018186803b158015610c2757600080fd5b505af4158015610c3b573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef63998745aa738d34dc2c33a6386e96ca562d8478eaf82305b81a6001600160a01b031663dca44f6f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ca657600080fd5b505afa158015610cba573d6000803e3d6000fd5b505050506040513d6020811015610cd057600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152738d34dc2c33a6386e96ca562d8478eaf82305b81a6024830152516044808301926000929190829003018186803b158015610d3157600080fd5b505af4158015610d45573d6000803e3d6000fd5b50505050610d51612222565b5060408051610220810182526d554e495632414156454554482d4160901b815273dfc14d2af169b0d36c4eff567ada9b2e0cae044f60208201527342afd448df7d96291551f1efe1a590101afb1dff918101919091527320d298ca96bf8c2000203b911908dbdc1a8bac586060820152738d34dc2c33a6386e96ca562d8478eaf82305b81a6080820152600160a0820181905260c0820152600060e0820152622dc6c06101008201526107d061012082015261c3506101408201526105146101608201526b033b2e3cb112f1349de86fd861018082015261012c6101a08201526154606101c082018190526101e0820152614074610200820152610e5481611675565b604080516319d900a160e01b81526b0aa9c92ac648282ac8a8aa8960a31b600482015273dfc14d2af169b0d36c4eff567ada9b2e0cae044f60248201529051739a6c490ba30507e732d61235eff94c26aea234ef916319d900a1916044808301926000929190829003018186803b158015610ece57600080fd5b505af4158015610ee2573d6000803e3d6000fd5b5050604080516319d900a160e01b81527f4d43445f4a4f494e5f554e495632414156454554485f4100000000000000000060048201527342afd448df7d96291551f1efe1a590101afb1dff60248201529051739a6c490ba30507e732d61235eff94c26aea234ef93506319d900a192506044808301926000929190829003018186803b158015610f7157600080fd5b505af4158015610f85573d6000803e3d6000fd5b5050604080516319d900a160e01b81527f4d43445f464c49505f554e495632414156454554485f4100000000000000000060048201527320d298ca96bf8c2000203b911908dbdc1a8bac5860248201529051739a6c490ba30507e732d61235eff94c26aea234ef93506319d900a192506044808301926000929190829003018186803b15801561101457600080fd5b505af4158015611028573d6000803e3d6000fd5b5050604080516319d900a160e01b81526f0a092a0beaa9c92ac648282ac8a8aa8960831b6004820152738d34dc2c33a6386e96ca562d8478eaf82305b81a60248201529051739a6c490ba30507e732d61235eff94c26aea234ef93506319d900a192506044808301926000929190829003018186803b1580156110aa57600080fd5b505af41580156110be573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef634ba2363a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561110657600080fd5b505af415801561111a573d6000803e3d6000fd5b505050506040513d602081101561113057600080fd5b505160408051634fb3c66560e11b815290516001600160a01b0390921691639f678cca916004808201926020929091908290030181600087803b15801561117657600080fd5b505af115801561118a573d6000803e3d6000fd5b505050506040513d60208110156111a057600080fd5b5050604080516365c0ac4b60e01b81526b033b2e3c9fdbc4151f15d0b060048201529051739a6c490ba30507e732d61235eff94c26aea234ef916365c0ac4b916024808301926000929190829003018186803b1580156111ff57600080fd5b505af4158015611213573d6000803e3d6000fd5b505050506000739a6c490ba30507e732d61235eff94c26aea234ef631307f3ab6040518163ffffffff1660e01b815260040160206040518083038186803b15801561125d57600080fd5b505af4158015611271573d6000803e3d6000fd5b505050506040513d602081101561128757600080fd5b505160408051636ffd800160e01b81526950534d2d555344432d4160b01b60048201529051919250739a6c490ba30507e732d61235eff94c26aea234ef91636d892f7e918391636ffd800191602480820192602092909190829003018186803b1580156112f357600080fd5b505af4158015611307573d6000803e3d6000fd5b505050506040513d602081101561131d57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b0392831660048201529185166024830152516044808301926000929190829003018186803b15801561136c57600080fd5b505af4158015611380573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef636d892f7e739a6c490ba30507e732d61235eff94c26aea234ef636ffd80016040518163ffffffff1660e01b815260040180806d554e495632444149555344432d4160901b815250602001905060206040518083038186803b1580156113fe57600080fd5b505af4158015611412573d6000803e3d6000fd5b505050506040513d602081101561142857600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b0392831660048201529185166024830152516044808301926000929190829003018186803b15801561147757600080fd5b505af415801561148b573d6000803e3d6000fd5b505050506000739a6c490ba30507e732d61235eff94c26aea234ef6336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156114d557600080fd5b505af41580156114e9573d6000803e3d6000fd5b505050506040513d60208110156114ff57600080fd5b50516040805163babe8a3f60e01b815290519192506001600160a01b038316916329ae811491839163babe8a3f91600480820192602092909190829003018186803b15801561154d57600080fd5b505afa158015611561573d6000803e3d6000fd5b505050506040513d602081101561157757600080fd5b5051604080516001600160e01b031960e085901b168152634c696e6560e01b6004820152721b0876d6cf3c6e33a0ca31ac1ad7a5706370f8909201602483015251604480830192600092919082900301818387803b1580156115d857600080fd5b505af11580156115ec573d6000803e3d6000fd5b505060408051635f3a7dd760e01b8152602060048201526005602482015264312e322e3760d81b60448201529051739a6c490ba30507e732d61235eff94c26aea234ef9350635f3a7dd792506064808301926000929190829003018186803b15801561165757600080fd5b505af415801561166b573d6000803e3d6000fd5b5050505050505050565b805160208201516040808401516060850151608086015183516337ff7eaf60e01b815260048101969096526001600160a01b03948516602487015291841660448601528316606485015291909116608483015251739a6c490ba30507e732d61235eff94c26aea234ef916337ff7eaf9160a4808301926000929190829003018186803b15801561170457600080fd5b505af4158015611718573d6000803e3d6000fd5b505050506000739a6c490ba30507e732d61235eff94c26aea234ef631307f3ab6040518163ffffffff1660e01b815260040160206040518083038186803b15801561176257600080fd5b505af4158015611776573d6000803e3d6000fd5b505050506040513d602081101561178c57600080fd5b5051606083015160408051632bef459560e01b81526001600160a01b039283166004820152918316602483015251919250739a6c490ba30507e732d61235eff94c26aea234ef91632bef459591604480820192600092909190829003018186803b1580156117f957600080fd5b505af415801561180d573d6000803e3d6000fd5b505050508160a0015161189a576060820151604080516336c497bf60e11b81526001600160a01b038085166004830152909216602483015251739a6c490ba30507e732d61235eff94c26aea234ef91636d892f7e916044808301926000929190829003018186803b15801561188157600080fd5b505af4158015611895573d6000803e3d6000fd5b505050505b8160c0015115611d0657739a6c490ba30507e732d61235eff94c26aea234ef632bef45958360800151739a6c490ba30507e732d61235eff94c26aea234ef63e475ac5d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561190757600080fd5b505af415801561191b573d6000803e3d6000fd5b505050506040513d602081101561193157600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926000929190829003018186803b15801561198157600080fd5b505af4158015611995573d6000803e3d6000fd5b505050508160e0015115611a9257739a6c490ba30507e732d61235eff94c26aea234ef63998745aa83608001516001600160a01b0316632e7dc6af6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119fa57600080fd5b505afa158015611a0e573d6000803e3d6000fd5b505050506040513d6020811015611a2457600080fd5b50516080850151604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926000929190829003018186803b158015611a7957600080fd5b505af4158015611a8d573d6000803e3d6000fd5b505050505b739a6c490ba30507e732d61235eff94c26aea234ef63ef13c7568360800151739a6c490ba30507e732d61235eff94c26aea234ef632e77468d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611af557600080fd5b505af4158015611b09573d6000803e3d6000fd5b505050506040513d6020811015611b1f57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926000929190829003018186803b158015611b6f57600080fd5b505af4158015611b83573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef63ef13c7568360800151739a6c490ba30507e732d61235eff94c26aea234ef63efbe1c1c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611bea57600080fd5b505af4158015611bfe573d6000803e3d6000fd5b505050506040513d6020811015611c1457600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926000929190829003018186803b158015611c6457600080fd5b505af4158015611c78573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef6389c32076836080015184600001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060006040518083038186803b158015611ced57600080fd5b505af4158015611d01573d6000803e3d6000fd5b505050505b739a6c490ba30507e732d61235eff94c26aea234ef637d2a54f48361010001516040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b158015611d5a57600080fd5b505af4158015611d6e573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef639976f02b83600001518461010001516040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015611dd257600080fd5b505af4158015611de6573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef635fc132c183600001518461012001516040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015611e4a57600080fd5b505af4158015611e5e573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef639bd0a56a83600001518461014001516040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015611ec257600080fd5b505af4158015611ed6573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef630daa5eb583600001518461016001516040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015611f3a57600080fd5b505af4158015611f4e573d6000803e3d6000fd5b505083516101808501516040805163072044c760e51b8152600481019390935260248301919091526001604483015251739a6c490ba30507e732d61235eff94c26aea234ef935063e40898e092506064808301926000929190829003018186803b158015611fbb57600080fd5b505af4158015611fcf573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef63956771e98360000151846101a001516040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b15801561203357600080fd5b505af4158015612047573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef63976e58668360000151846101c001516040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b1580156120ab57600080fd5b505af41580156120bf573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef638a63cf0b8360000151846101e001516040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b15801561212357600080fd5b505af4158015612137573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef63bdc56f3083600001518461020001516040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b15801561219b57600080fd5b505af41580156121af573d6000803e3d6000fd5b50505050739a6c490ba30507e732d61235eff94c26aea234ef636d530fb383600001516040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561220657600080fd5b505af415801561221a573d6000803e3d6000fd5b505050505050565b6040518061022001604052806000801916815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600015158152602001600015158152602001600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509056fe323032312d30322d3139204d616b657244414f20457865637574697665205370656c6c207c20486173683a20307865646366313735323032323335353662313263353335616265376466633863373066346639386434343233313139613035613337623932623138303438626361a26469706673582212209b08f7e6d1f1bad2b2e7938fd3769ec36d8bc3d3111b3874f05da6acb381763d64736f6c634300060b0033

Deployed ByteCode Sourcemap

59873:199:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44569:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44693:37;;;:::i;:::-;;;;-1:-1:-1;;;;;44693:37:0;;;;;;;;;;;;;;44737:41;;;:::i;:::-;;;;;;;;;;;;;;;;44429:92;;;:::i;44652:34::-;;;:::i;45110:111::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;45059:42;;;:::i;44785:36::-;;;:::i;47664:144::-;;;:::i;:::-;;44610:35;;;:::i;47391:265::-;;;:::i;44528:34::-;;;:::i;45229:1385::-;;;:::i;44569:34::-;;;;;;;;;;;;;;;-1:-1:-1;;44569:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;44693:37::-;;;:::o;44737:41::-;;;:::o;44429:92::-;44478:42;44429:92;:::o;44652:34::-;;;:::o;45110:111::-;45156:4;45192:6;-1:-1:-1;;;;;45180:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45180:33:0;;-1:-1:-1;45110:111:0;;:::o;45059:42::-;;;;;;;;;;;;;;;-1:-1:-1;;45059:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44785:36;;;:::o;47664:144::-;47707:4;;;;47706:5;47698:36;;;;;-1:-1:-1;;;47698:36:0;;;;;;;;;;;;-1:-1:-1;;;47698:36:0;;;;;;;;;;;;;;;47745:4;:11;;-1:-1:-1;;47745:11:0;47752:4;47745:11;;;;;:4;47796:3;47767:33;;-1:-1:-1;;;47767:33:0;;47778:6;-1:-1:-1;;;;;47767:33:0;;;;;;;;;47786:3;47767:33;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47767:33:0;;;;47745:11;47767:33;;;;;;;;;;;;;:5;:10;;;;;;;47778:6;;47786:3;;47796;;47767:33;;;;;47752:4;;47767:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47767:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47767:33:0;;;;;;;;;;-1:-1:-1;47767:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47664:144::o;44610:35::-;;;;;;:::o;47391:265::-;47444:10;47437:3;:17;;47429:55;;;;;-1:-1:-1;;;47429:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;47503:3;;:8;47495:58;;;;-1:-1:-1;;;47495:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47590:5;-1:-1:-1;;;;;47576:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47576:28:0;47570:3;:34;47564:3;:40;;;47615:33;;-1:-1:-1;;;47615:33:0;;-1:-1:-1;;;;;47626:6:0;47615:33;;;;;;;;;47634:3;47615:33;;;;;;;;;;;;;;;;;;;47639:3;47615:33;;;;;;;;;-1:-1:-1;;47615:33:0;;;;;;;;;;;:5;:10;;;;;;47626:6;;47634:3;;47639;;47570:34;;47615:33;;;;;;47639:3;;47615:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47391:265::o;44528:34::-;;;;:::o;45229:1385::-;45276:16;45313:3;;45305:48;;;;;-1:-1:-1;;;45305:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;45393:3;;45375:15;:21;:45;;45417:3;;45375:45;;;45399:15;45375:45;45364:56;;45469:6;-1:-1:-1;;;;;45457:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45457:33:0;45453:1154;;;45550:1;45536:6;45525:17;;45545:1;45525:21;45524:27;45604:2;45594:7;45583:18;;:23;45661:2;45638:20;;;:25;;;;45695:13;;45736:1;45729:8;;45725:871;;45775:3;45771:1;:7;45782:6;45770:18;45758:30;;;;45863:4;45858:2;:9;45870:2;45858:14;45876:7;45857:26;45845:38;;;;45969:6;45948;45957:9;45948:18;:27;45936:39;;;;45725:871;;;46054:2;46046:4;:10;46042:539;;46085:3;46092:1;46085:8;46081:32;;;46107:6;46095:18;;;;46081:32;46207:4;46202:2;:9;46214:2;46202:14;46220:7;46201:26;46189:38;;;;46315:6;46294;46303:9;46294:18;:27;46282:39;;;;46042:539;;;46380:2;46373:4;:9;46369:212;;;46425:4;46420:2;:9;46433:7;46419:21;46407:33;;;;46533:6;46512;46521:9;46512:18;:27;46500:39;;;;46369:212;45453:1154;;;;45229:1385;:::o

Swarm Source

ipfs://9b08f7e6d1f1bad2b2e7938fd3769ec36d8bc3d3111b3874f05da6acb381763d
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.