Contract Address Details

0xE14C7aD35dda18Ab89b3baB054CC7D944435eDf7

Contract Name
DssProxyActions
Creator
0xb8f7fd–af46bc at 0x050ce2–e962b8
Balance
0 VLX
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
69800059
Contract name:
DssProxyActions




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




Optimization runs
200
EVM Version
petersburg




Verified at
2021-10-28T21:00:47.049296Z

Contract source code

pragma solidity >=0.5.12;

interface GemLike {
    function approve(address, uint) external;
    function transfer(address, uint) external;
    function transferFrom(address, address, uint) external;
    function deposit() external payable;
    function withdraw(uint) external;
}

interface ManagerLike {
    function cdpCan(address, uint, address) external view returns (uint);
    function ilks(uint) external view returns (bytes32);
    function owns(uint) external view returns (address);
    function urns(uint) external view returns (address);
    function vat() external view returns (address);
    function open(bytes32, address) external returns (uint);
    function give(uint, address) external;
    function cdpAllow(uint, address, uint) external;
    function urnAllow(address, uint) external;
    function frob(uint, int, int) external;
    function flux(uint, address, uint) external;
    function move(uint, address, uint) external;
    function exit(address, uint, address, uint) external;
    function quit(uint, address) external;
    function enter(address, uint) external;
    function shift(uint, uint) external;
}

interface VatLike {
    function can(address, address) external view returns (uint);
    function ilks(bytes32) external view returns (uint, uint, uint, uint, uint);
    function usdv(address) external view returns (uint);
    function urns(bytes32, address) external view returns (uint, uint);
    function frob(bytes32, address, address, address, int, int) external;
    function hope(address) external;
    function move(address, address, uint) external;
}

interface GemJoinLike {
    function dec() external returns (uint);
    function gem() external returns (GemLike);
    function join(address, uint) external payable;
    function exit(address, uint) external;
}

interface GNTJoinLike {
    function bags(address) external view returns (address);
    function make(address) external returns (address);
}

interface UsdvJoinLike {
    function vat() external returns (VatLike);
    function usdv() external returns (GemLike);
    function join(address, uint) external payable;
    function exit(address, uint) external;
}

interface HopeLike {
    function hope(address) external;
    function nope(address) external;
}

interface EndLike {
    function fix(bytes32) external view returns (uint);
    function cash(bytes32, uint) external;
    function free(bytes32) external;
    function pack(uint) external;
    function skim(bytes32, address) external;
}

interface JugLike {
    function drip(bytes32) external returns (uint);
}

interface PotLike {
    function pie(address) external view returns (uint);
    function drip() external returns (uint);
    function join(uint) external;
    function exit(uint) external;
}

interface ProxyRegistryLike {
    function proxies(address) external view returns (address);
    function build(address) external returns (address);
}

interface ProxyLike {
    function owner() external view returns (address);
}

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// WARNING: These functions meant to be used as a a library for a DSProxy. Some are unsafe if you call them directly.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

contract Common {
    uint256 constant RAY = 10 ** 27;

    // Internal functions

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

    // Public functions

    function usdvJoin_join(address apt, address urn, uint wad) public {
        // Gets USDV from the user's wallet
        UsdvJoinLike(apt).usdv().transferFrom(msg.sender, address(this), wad);
        // Approves adapter to take the USDV amount
        UsdvJoinLike(apt).usdv().approve(apt, wad);
        // Joins USDV into the vat
        UsdvJoinLike(apt).join(urn, wad);
    }
}

contract DssProxyActions is Common {
    // Internal functions

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

    function toInt(uint x) internal pure returns (int y) {
        y = int(x);
        require(y >= 0, "int-overflow");
    }

    function toRad(uint wad) internal pure returns (uint rad) {
        rad = mul(wad, 10 ** 27);
    }

    function convertTo18(address gemJoin, uint256 amt) internal returns (uint256 wad) {
        // For those collaterals that have less than 18 decimals precision we need to do the conversion before passing to frob function
        // Adapters will automatically handle the difference of precision
        wad = mul(
            amt,
            10 ** (18 - GemJoinLike(gemJoin).dec())
        );
    }

    function _getDrawDart(
        address vat,
        address jug,
        address urn,
        bytes32 ilk,
        uint wad
    ) internal returns (int dart) {
        // Updates stability fee rate
        uint rate = JugLike(jug).drip(ilk);

        // Gets USDV balance of the urn in the vat
        uint usdv = VatLike(vat).usdv(urn);

        // If there was already enough USDV in the vat balance, just exits it without adding more debt
        if (usdv < mul(wad, RAY)) {
            // Calculates the needed dart so together with the existing usdv in the vat is enough to exit wad amount of USDV tokens
            dart = toInt(sub(mul(wad, RAY), usdv) / rate);
            // This is neeeded due lack of precision. It might need to sum an extra dart wei (for the given USDV wad amount)
            dart = mul(uint(dart), rate) < mul(wad, RAY) ? dart + 1 : dart;
        }
    }

    function _getWipeDart(
        address vat,
        uint usdv,
        address urn,
        bytes32 ilk
    ) internal view returns (int dart) {
        // Gets actual rate from the vat
        (, uint rate,,,) = VatLike(vat).ilks(ilk);
        // Gets actual art value of the urn
        (, uint art) = VatLike(vat).urns(ilk, urn);

        // Uses the whole usdv balance in the vat to reduce the debt
        dart = toInt(usdv / rate);
        // Checks the calculated dart is not higher than urn.art (total debt), otherwise uses its value
        dart = uint(dart) <= art ? - dart : - toInt(art);
    }

    function _getWipeAllWad(
        address vat,
        address usr,
        address urn,
        bytes32 ilk
    ) internal view returns (uint wad) {
        // Gets actual rate from the vat
        (, uint rate,,,) = VatLike(vat).ilks(ilk);
        // Gets actual art value of the urn
        (, uint art) = VatLike(vat).urns(ilk, urn);
        // Gets actual usdv amount in the urn
        uint usdv = VatLike(vat).usdv(usr);

        uint rad = sub(mul(art, rate), usdv);
        wad = rad / RAY;

        // If the rad precision has some dust, it will need to request for 1 extra wad wei
        wad = mul(wad, RAY) < rad ? wad + 1 : wad;
    }

    // Public functions

    function transfer(address gem, address dst, uint amt) public {
        GemLike(gem).transfer(dst, amt);
    }

    function vlxJoin_join(address apt, address urn) public payable {
        // Wraps VLX in WVLX
        GemJoinLike(apt).gem().deposit.value(msg.value)();
        // Approves adapter to take the WVLX amount
        GemJoinLike(apt).gem().approve(address(apt), msg.value);
        // Joins WVLX collateral into the vat
        GemJoinLike(apt).join(urn, msg.value);
    }

    function gemJoin_join(address apt, address urn, uint amt, bool transferFrom) public {
        // Only executes for tokens that have approval/transferFrom implementation
        if (transferFrom) {
            // Gets token from the user's wallet
            GemJoinLike(apt).gem().transferFrom(msg.sender, address(this), amt);
            // Approves adapter to take the token amount
            GemJoinLike(apt).gem().approve(apt, amt);
        }
        // Joins token collateral into the vat
        GemJoinLike(apt).join(urn, amt);
    }

    function hope(
        address obj,
        address usr
    ) public {
        HopeLike(obj).hope(usr);
    }

    function nope(
        address obj,
        address usr
    ) public {
        HopeLike(obj).nope(usr);
    }

    function open(
        address manager,
        bytes32 ilk,
        address usr
    ) public returns (uint cdp) {
        cdp = ManagerLike(manager).open(ilk, usr);
    }

    function give(
        address manager,
        uint cdp,
        address usr
    ) public {
        ManagerLike(manager).give(cdp, usr);
    }

    function giveToProxy(
        address proxyRegistry,
        address manager,
        uint cdp,
        address dst
    ) public {
        // Gets actual proxy address
        address proxy = ProxyRegistryLike(proxyRegistry).proxies(dst);
        // Checks if the proxy address already existed and dst address is still the owner
        if (proxy == address(0) || ProxyLike(proxy).owner() != dst) {
            uint csize;
            assembly {
                csize := extcodesize(dst)
            }
            // We want to avoid creating a proxy for a contract address that might not be able to handle proxies, then losing the CDP
            require(csize == 0, "Dst-is-a-contract");
            // Creates the proxy for the dst address
            proxy = ProxyRegistryLike(proxyRegistry).build(dst);
        }
        // Transfers CDP to the dst proxy
        give(manager, cdp, proxy);
    }

    function cdpAllow(
        address manager,
        uint cdp,
        address usr,
        uint ok
    ) public {
        ManagerLike(manager).cdpAllow(cdp, usr, ok);
    }

    function urnAllow(
        address manager,
        address usr,
        uint ok
    ) public {
        ManagerLike(manager).urnAllow(usr, ok);
    }

    function flux(
        address manager,
        uint cdp,
        address dst,
        uint wad
    ) public {
        ManagerLike(manager).flux(cdp, dst, wad);
    }

    function move(
        address manager,
        uint cdp,
        address dst,
        uint rad
    ) public {
        ManagerLike(manager).move(cdp, dst, rad);
    }

    function frob(
        address manager,
        uint cdp,
        int dink,
        int dart
    ) public {
        ManagerLike(manager).frob(cdp, dink, dart);
    }

    function quit(
        address manager,
        uint cdp,
        address dst
    ) public {
        ManagerLike(manager).quit(cdp, dst);
    }

    function enter(
        address manager,
        address src,
        uint cdp
    ) public {
        ManagerLike(manager).enter(src, cdp);
    }

    function shift(
        address manager,
        uint cdpSrc,
        uint cdpOrg
    ) public {
        ManagerLike(manager).shift(cdpSrc, cdpOrg);
    }

    function makeGemBag(
        address gemJoin
    ) public returns (address bag) {
        bag = GNTJoinLike(gemJoin).make(address(this));
    }

    function lockVLX(
        address manager,
        address vlxJoin,
        uint cdp
    ) public payable {
        // Receives VLX amount, converts it to WVLX and joins it into the vat
        vlxJoin_join(vlxJoin, address(this));
        // Locks WVLX amount into the CDP
        VatLike(ManagerLike(manager).vat()).frob(
            ManagerLike(manager).ilks(cdp),
            ManagerLike(manager).urns(cdp),
            address(this),
            address(this),
            toInt(msg.value),
            0
        );
    }

    function safeLockVLX(
        address manager,
        address vlxJoin,
        uint cdp,
        address owner
    ) public payable {
        require(ManagerLike(manager).owns(cdp) == owner, "owner-missmatch");
        lockVLX(manager, vlxJoin, cdp);
    }

    function lockGem(
        address manager,
        address gemJoin,
        uint cdp,
        uint amt,
        bool transferFrom
    ) public {
        // Takes token amount from user's wallet and joins into the vat
        gemJoin_join(gemJoin, address(this), amt, transferFrom);
        // Locks token amount into the CDP
        VatLike(ManagerLike(manager).vat()).frob(
            ManagerLike(manager).ilks(cdp),
            ManagerLike(manager).urns(cdp),
            address(this),
            address(this),
            toInt(convertTo18(gemJoin, amt)),
            0
        );
    }

    function safeLockGem(
        address manager,
        address gemJoin,
        uint cdp,
        uint amt,
        bool transferFrom,
        address owner
    ) public {
        require(ManagerLike(manager).owns(cdp) == owner, "owner-missmatch");
        lockGem(manager, gemJoin, cdp, amt, transferFrom);
    }

    function freeVLX(
        address manager,
        address vlxJoin,
        uint cdp,
        uint wad
    ) public {
        // Unlocks WVLX amount from the CDP
        frob(manager, cdp, -toInt(wad), 0);
        // Moves the amount from the CDP urn to proxy's address
        flux(manager, cdp, address(this), wad);
        // Exits WVLX amount to proxy address as a token
        GemJoinLike(vlxJoin).exit(address(this), wad);
        // Converts WVLX to VLX
        GemJoinLike(vlxJoin).gem().withdraw(wad);
        // Sends VLX back to the user's wallet
        msg.sender.transfer(wad);
    }

    function freeGem(
        address manager,
        address gemJoin,
        uint cdp,
        uint amt
    ) public {
        uint wad = convertTo18(gemJoin, amt);
        // Unlocks token amount from the CDP
        frob(manager, cdp, -toInt(wad), 0);
        // Moves the amount from the CDP urn to proxy's address
        flux(manager, cdp, address(this), wad);
        // Exits token amount to the user's wallet as a token
        GemJoinLike(gemJoin).exit(msg.sender, amt);
    }

    function exitVLX(
        address manager,
        address vlxJoin,
        uint cdp,
        uint wad
    ) public {
        // Moves the amount from the CDP urn to proxy's address
        flux(manager, cdp, address(this), wad);

        // Exits WVLX amount to proxy address as a token
        GemJoinLike(vlxJoin).exit(address(this), wad);
        // Converts WVLX to VLX
        GemJoinLike(vlxJoin).gem().withdraw(wad);
        // Sends VLX back to the user's wallet
        msg.sender.transfer(wad);
    }

    function exitGem(
        address manager,
        address gemJoin,
        uint cdp,
        uint amt
    ) public {
        // Moves the amount from the CDP urn to proxy's address
        flux(manager, cdp, address(this), convertTo18(gemJoin, amt));

        // Exits token amount to the user's wallet as a token
        GemJoinLike(gemJoin).exit(msg.sender, amt);
    }

    function draw(
        address manager,
        address jug,
        address usdvJoin,
        uint cdp,
        uint wad
    ) public {
        address urn = ManagerLike(manager).urns(cdp);
        address vat = ManagerLike(manager).vat();
        bytes32 ilk = ManagerLike(manager).ilks(cdp);
        // Generates debt in the CDP
        frob(manager, cdp, 0, _getDrawDart(vat, jug, urn, ilk, wad));
        // Moves the USDV amount (balance in the vat in rad) to proxy's address
        move(manager, cdp, address(this), toRad(wad));
        // Allows adapter to access to proxy's USDV balance in the vat
        if (VatLike(vat).can(address(this), address(usdvJoin)) == 0) {
            VatLike(vat).hope(usdvJoin);
        }
        // Exits USDV to the user's wallet as a token
        UsdvJoinLike(usdvJoin).exit(msg.sender, wad);
    }

    function wipe(
        address manager,
        address usdvJoin,
        uint cdp,
        uint wad
    ) public {
        address vat = ManagerLike(manager).vat();
        address urn = ManagerLike(manager).urns(cdp);
        bytes32 ilk = ManagerLike(manager).ilks(cdp);

        address own = ManagerLike(manager).owns(cdp);
        if (own == address(this) || ManagerLike(manager).cdpCan(own, cdp, address(this)) == 1) {
            // Joins USDV amount into the vat
            usdvJoin_join(usdvJoin, urn, wad);
            // Paybacks debt to the CDP
            frob(manager, cdp, 0, _getWipeDart(vat, VatLike(vat).usdv(urn), urn, ilk));
        } else {
             // Joins USDV amount into the vat
            usdvJoin_join(usdvJoin, address(this), wad);
            // Paybacks debt to the CDP
            VatLike(vat).frob(
                ilk,
                urn,
                address(this),
                address(this),
                0,
                _getWipeDart(vat, wad * RAY, urn, ilk)
            );
        }
    }

    function safeWipe(
        address manager,
        address usdvJoin,
        uint cdp,
        uint wad,
        address owner
    ) public {
        require(ManagerLike(manager).owns(cdp) == owner, "owner-missmatch");
        wipe(manager, usdvJoin, cdp, wad);
    }

    function wipeAll(
        address manager,
        address usdvJoin,
        uint cdp
    ) public {
        address vat = ManagerLike(manager).vat();
        address urn = ManagerLike(manager).urns(cdp);
        bytes32 ilk = ManagerLike(manager).ilks(cdp);
        (, uint art) = VatLike(vat).urns(ilk, urn);

        address own = ManagerLike(manager).owns(cdp);
        if (own == address(this) || ManagerLike(manager).cdpCan(own, cdp, address(this)) == 1) {
            // Joins USDV amount into the vat
            usdvJoin_join(usdvJoin, urn, _getWipeAllWad(vat, urn, urn, ilk));
            // Paybacks debt to the CDP
            frob(manager, cdp, 0, -int(art));
        } else {
            // Joins USDV amount into the vat
            usdvJoin_join(usdvJoin, address(this), _getWipeAllWad(vat, address(this), urn, ilk));
            // Paybacks debt to the CDP
            VatLike(vat).frob(
                ilk,
                urn,
                address(this),
                address(this),
                0,
                -int(art)
            );
        }
    }

    function safeWipeAll(
        address manager,
        address usdvJoin,
        uint cdp,
        address owner
    ) public {
        require(ManagerLike(manager).owns(cdp) == owner, "owner-missmatch");
        wipeAll(manager, usdvJoin, cdp);
    }

    function lockVLXAndDraw(
        address manager,
        address jug,
        address vlxJoin,
        address usdvJoin,
        uint cdp,
        uint wadD
    ) public payable {
        address urn = ManagerLike(manager).urns(cdp);
        address vat = ManagerLike(manager).vat();
        bytes32 ilk = ManagerLike(manager).ilks(cdp);
        // Receives VLX amount, converts it to WVLX and joins it into the vat
        vlxJoin_join(vlxJoin, urn);
        // Locks WVLX amount into the CDP and generates debt
        frob(manager, cdp, toInt(msg.value), _getDrawDart(vat, jug, urn, ilk, wadD));
        // Moves the USDV amount (balance in the vat in rad) to proxy's address
        move(manager, cdp, address(this), toRad(wadD));
        // Allows adapter to access to proxy's USDV balance in the vat
        if (VatLike(vat).can(address(this), address(usdvJoin)) == 0) {
            VatLike(vat).hope(usdvJoin);
        }
        // Exits USDV to the user's wallet as a token
        UsdvJoinLike(usdvJoin).exit(msg.sender, wadD);
    }

    function openLockVLXAndDraw(
        address manager,
        address jug,
        address vlxJoin,
        address usdvJoin,
        bytes32 ilk,
        uint wadD
    ) public payable returns (uint cdp) {
        cdp = open(manager, ilk, address(this));
        lockVLXAndDraw(manager, jug, vlxJoin, usdvJoin, cdp, wadD);
    }

    function lockGemAndDraw(
        address manager,
        address jug,
        address gemJoin,
        address usdvJoin,
        uint cdp,
        uint amtC,
        uint wadD,
        bool transferFrom
    ) public {
        address urn = ManagerLike(manager).urns(cdp);
        address vat = ManagerLike(manager).vat();
        bytes32 ilk = ManagerLike(manager).ilks(cdp);
        // Takes token amount from user's wallet and joins into the vat
        gemJoin_join(gemJoin, urn, amtC, transferFrom);
        // Locks token amount into the CDP and generates debt
        frob(manager, cdp, toInt(convertTo18(gemJoin, amtC)), _getDrawDart(vat, jug, urn, ilk, wadD));
        // Moves the USDV amount (balance in the vat in rad) to proxy's address
        move(manager, cdp, address(this), toRad(wadD));
        // Allows adapter to access to proxy's USDV balance in the vat
        if (VatLike(vat).can(address(this), address(usdvJoin)) == 0) {
            VatLike(vat).hope(usdvJoin);
        }
        // Exits USDV to the user's wallet as a token
        UsdvJoinLike(usdvJoin).exit(msg.sender, wadD);
    }

    function openLockGemAndDraw(
        address manager,
        address jug,
        address gemJoin,
        address usdvJoin,
        bytes32 ilk,
        uint amtC,
        uint wadD,
        bool transferFrom
    ) public returns (uint cdp) {
        cdp = open(manager, ilk, address(this));
        lockGemAndDraw(manager, jug, gemJoin, usdvJoin, cdp, amtC, wadD, transferFrom);
    }

    function openLockGNTAndDraw(
        address manager,
        address jug,
        address gntJoin,
        address usdvJoin,
        bytes32 ilk,
        uint amtC,
        uint wadD
    ) public returns (address bag, uint cdp) {
        // Creates bag (if doesn't exist) to hold GNT
        bag = GNTJoinLike(gntJoin).bags(address(this));
        if (bag == address(0)) {
            bag = makeGemBag(gntJoin);
        }
        // Transfer funds to the funds which previously were sent to the proxy
        GemLike(GemJoinLike(gntJoin).gem()).transfer(bag, amtC);
        cdp = openLockGemAndDraw(manager, jug, gntJoin, usdvJoin, ilk, amtC, wadD, false);
    }

    function wipeAndFreeVLX(
        address manager,
        address vlxJoin,
        address usdvJoin,
        uint cdp,
        uint wadC,
        uint wadD
    ) public {
        address urn = ManagerLike(manager).urns(cdp);
        // Joins USDV amount into the vat
        usdvJoin_join(usdvJoin, urn, wadD);
        // Paybacks debt to the CDP and unlocks WVLX amount from it
        frob(
            manager,
            cdp,
            -toInt(wadC),
            _getWipeDart(ManagerLike(manager).vat(), VatLike(ManagerLike(manager).vat()).usdv(urn), urn, ManagerLike(manager).ilks(cdp))
        );
        // Moves the amount from the CDP urn to proxy's address
        flux(manager, cdp, address(this), wadC);
        // Exits WVLX amount to proxy address as a token
        GemJoinLike(vlxJoin).exit(address(this), wadC);
        // Converts WVLX to VLX
        GemJoinLike(vlxJoin).gem().withdraw(wadC);
        // Sends VLX back to the user's wallet
        msg.sender.transfer(wadC);
    }

    function wipeAllAndFreeVLX(
        address manager,
        address vlxJoin,
        address usdvJoin,
        uint cdp,
        uint wadC
    ) public {
        address vat = ManagerLike(manager).vat();
        address urn = ManagerLike(manager).urns(cdp);
        bytes32 ilk = ManagerLike(manager).ilks(cdp);
        (, uint art) = VatLike(vat).urns(ilk, urn);

        // Joins USDV amount into the vat
        usdvJoin_join(usdvJoin, urn, _getWipeAllWad(vat, urn, urn, ilk));
        // Paybacks debt to the CDP and unlocks WVLX amount from it
        frob(
            manager,
            cdp,
            -toInt(wadC),
            -int(art)
        );
        // Moves the amount from the CDP urn to proxy's address
        flux(manager, cdp, address(this), wadC);
        // Exits WVLX amount to proxy address as a token
        GemJoinLike(vlxJoin).exit(address(this), wadC);
        // Converts WVLX to VLX
        GemJoinLike(vlxJoin).gem().withdraw(wadC);
        // Sends VLX back to the user's wallet
        msg.sender.transfer(wadC);
    }

    function wipeAndFreeGem(
        address manager,
        address gemJoin,
        address usdvJoin,
        uint cdp,
        uint amtC,
        uint wadD
    ) public {
        address urn = ManagerLike(manager).urns(cdp);
        // Joins USDV amount into the vat
        usdvJoin_join(usdvJoin, urn, wadD);
        uint wadC = convertTo18(gemJoin, amtC);
        // Paybacks debt to the CDP and unlocks token amount from it
        frob(
            manager,
            cdp,
            -toInt(wadC),
            _getWipeDart(ManagerLike(manager).vat(), VatLike(ManagerLike(manager).vat()).usdv(urn), urn, ManagerLike(manager).ilks(cdp))
        );
        // Moves the amount from the CDP urn to proxy's address
        flux(manager, cdp, address(this), wadC);
        // Exits token amount to the user's wallet as a token
        GemJoinLike(gemJoin).exit(msg.sender, amtC);
    }

    function wipeAllAndFreeGem(
        address manager,
        address gemJoin,
        address usdvJoin,
        uint cdp,
        uint amtC
    ) public {
        address vat = ManagerLike(manager).vat();
        address urn = ManagerLike(manager).urns(cdp);
        bytes32 ilk = ManagerLike(manager).ilks(cdp);
        (, uint art) = VatLike(vat).urns(ilk, urn);

        // Joins USDV amount into the vat
        usdvJoin_join(usdvJoin, urn, _getWipeAllWad(vat, urn, urn, ilk));
        uint wadC = convertTo18(gemJoin, amtC);
        // Paybacks debt to the CDP and unlocks token amount from it
        frob(
            manager,
            cdp,
            -toInt(wadC),
            -int(art)
        );
        // Moves the amount from the CDP urn to proxy's address
        flux(manager, cdp, address(this), wadC);
        // Exits token amount to the user's wallet as a token
        GemJoinLike(gemJoin).exit(msg.sender, amtC);
    }
}

contract DssProxyActionsEnd is Common {
    // Internal functions

    function _free(
        address manager,
        address end,
        uint cdp
    ) internal returns (uint ink) {
        bytes32 ilk = ManagerLike(manager).ilks(cdp);
        address urn = ManagerLike(manager).urns(cdp);
        VatLike vat = VatLike(ManagerLike(manager).vat());
        uint art;
        (ink, art) = vat.urns(ilk, urn);

        // If CDP still has debt, it needs to be paid
        if (art > 0) {
            EndLike(end).skim(ilk, urn);
            (ink,) = vat.urns(ilk, urn);
        }
        // Approves the manager to transfer the position to proxy's address in the vat
        if (vat.can(address(this), address(manager)) == 0) {
            vat.hope(manager);
        }
        // Transfers position from CDP to the proxy address
        ManagerLike(manager).quit(cdp, address(this));
        // Frees the position and recovers the collateral in the vat registry
        EndLike(end).free(ilk);
    }

    // Public functions
    function freeVLX(
        address manager,
        address vlxJoin,
        address end,
        uint cdp
    ) public {
        uint wad = _free(manager, end, cdp);
        // Exits WVLX amount to proxy address as a token
        GemJoinLike(vlxJoin).exit(address(this), wad);
        // Converts WVLX to VLX
        GemJoinLike(vlxJoin).gem().withdraw(wad);
        // Sends VLX back to the user's wallet
        msg.sender.transfer(wad);
    }

    function freeGem(
        address manager,
        address gemJoin,
        address end,
        uint cdp
    ) public {
        uint amt = _free(manager, end, cdp) / 10 ** (18 - GemJoinLike(gemJoin).dec());
        // Exits token amount to the user's wallet as a token
        GemJoinLike(gemJoin).exit(msg.sender, amt);
    }

    function pack(
        address usdvJoin,
        address end,
        uint wad
    ) public {
        usdvJoin_join(usdvJoin, address(this), wad);
        VatLike vat = UsdvJoinLike(usdvJoin).vat();
        // Approves the end to take out USDV from the proxy's balance in the vat
        if (vat.can(address(this), address(end)) == 0) {
            vat.hope(end);
        }
        EndLike(end).pack(wad);
    }

    function cashVLX(
        address vlxJoin,
        address end,
        bytes32 ilk,
        uint wad
    ) public {
        EndLike(end).cash(ilk, wad);
        uint wadC = mul(wad, EndLike(end).fix(ilk)) / RAY;
        // Exits WVLX amount to proxy address as a token
        GemJoinLike(vlxJoin).exit(address(this), wadC);
        // Converts WVLX to VLX
        GemJoinLike(vlxJoin).gem().withdraw(wadC);
        // Sends VLX back to the user's wallet
        msg.sender.transfer(wadC);
    }

    function cashGem(
        address gemJoin,
        address end,
        bytes32 ilk,
        uint wad
    ) public {
        EndLike(end).cash(ilk, wad);
        // Exits token amount to the user's wallet as a token
        uint amt = mul(wad, EndLike(end).fix(ilk)) / RAY / 10 ** (18 - GemJoinLike(gemJoin).dec());
        GemJoinLike(gemJoin).exit(msg.sender, amt);
    }
}

contract DssProxyActionsDsr is Common {
    function join(
        address usdvJoin,
        address pot,
        uint wad
    ) public {
        VatLike vat = UsdvJoinLike(usdvJoin).vat();
        // Executes drip to get the chi rate updated to rho == now, otherwise join will fail
        uint chi = PotLike(pot).drip();
        // Joins wad amount to the vat balance
        usdvJoin_join(usdvJoin, address(this), wad);
        // Approves the pot to take out USDV from the proxy's balance in the vat
        if (vat.can(address(this), address(pot)) == 0) {
            vat.hope(pot);
        }
        // Joins the pie value (equivalent to the USDV wad amount) in the pot
        PotLike(pot).join(mul(wad, RAY) / chi);
    }

    function exit(
        address usdvJoin,
        address pot,
        uint wad
    ) public {
        VatLike vat = UsdvJoinLike(usdvJoin).vat();
        // Executes drip to count the savings accumulated until this moment
        uint chi = PotLike(pot).drip();
        // Calculates the pie value in the pot equivalent to the USDV wad amount
        uint pie = mul(wad, RAY) / chi;
        // Exits USDV from the pot
        PotLike(pot).exit(pie);
        // Checks the actual balance of USDV in the vat after the pot exit
        uint bal = UsdvJoinLike(usdvJoin).vat().usdv(address(this));
        // Allows adapter to access to proxy's USDV balance in the vat
        if (vat.can(address(this), address(usdvJoin)) == 0) {
            vat.hope(usdvJoin);
        }
        // It is necessary to check if due rounding the exact wad amount can be exited by the adapter.
        // Otherwise it will do the maximum USDV balance in the vat
        UsdvJoinLike(usdvJoin).exit(
            msg.sender,
            bal >= mul(wad, RAY) ? wad : bal / RAY
        );
    }

    function exitAll(
        address usdvJoin,
        address pot
    ) public {
        VatLike vat = UsdvJoinLike(usdvJoin).vat();
        // Executes drip to count the savings accumulated until this moment
        uint chi = PotLike(pot).drip();
        // Gets the total pie belonging to the proxy address
        uint pie = PotLike(pot).pie(address(this));
        // Exits USDV from the pot
        PotLike(pot).exit(pie);
        // Allows adapter to access to proxy's USDV balance in the vat
        if (vat.can(address(this), address(usdvJoin)) == 0) {
            vat.hope(usdvJoin);
        }
        // Exits the USDV amount corresponding to the value of pie
        UsdvJoinLike(usdvJoin).exit(msg.sender, mul(chi, pie) / RAY);
    }
}
        

Contract ABI

[{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"cdpAllow","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"address","name":"usr","internalType":"address"},{"type":"uint256","name":"ok","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"draw","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"jug","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"wad","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"enter","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"src","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"exitGem","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"gemJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"amt","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"exitVLX","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"vlxJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"wad","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"flux","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"address","name":"dst","internalType":"address"},{"type":"uint256","name":"wad","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"freeGem","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"gemJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"amt","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"freeVLX","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"vlxJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"wad","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"frob","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"int256","name":"dink","internalType":"int256"},{"type":"int256","name":"dart","internalType":"int256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"gemJoin_join","inputs":[{"type":"address","name":"apt","internalType":"address"},{"type":"address","name":"urn","internalType":"address"},{"type":"uint256","name":"amt","internalType":"uint256"},{"type":"bool","name":"transferFrom","internalType":"bool"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"give","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"address","name":"usr","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"giveToProxy","inputs":[{"type":"address","name":"proxyRegistry","internalType":"address"},{"type":"address","name":"manager","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"address","name":"dst","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"hope","inputs":[{"type":"address","name":"obj","internalType":"address"},{"type":"address","name":"usr","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"lockGem","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"gemJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"amt","internalType":"uint256"},{"type":"bool","name":"transferFrom","internalType":"bool"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"lockGemAndDraw","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"jug","internalType":"address"},{"type":"address","name":"gemJoin","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"amtC","internalType":"uint256"},{"type":"uint256","name":"wadD","internalType":"uint256"},{"type":"bool","name":"transferFrom","internalType":"bool"}],"constant":false},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"lockVLX","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"vlxJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"lockVLXAndDraw","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"jug","internalType":"address"},{"type":"address","name":"vlxJoin","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"wadD","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"address","name":"bag","internalType":"address"}],"name":"makeGemBag","inputs":[{"type":"address","name":"gemJoin","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"move","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"address","name":"dst","internalType":"address"},{"type":"uint256","name":"rad","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"nope","inputs":[{"type":"address","name":"obj","internalType":"address"},{"type":"address","name":"usr","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint256","name":"cdp","internalType":"uint256"}],"name":"open","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"bytes32","name":"ilk","internalType":"bytes32"},{"type":"address","name":"usr","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"address","name":"bag","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"}],"name":"openLockGNTAndDraw","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"jug","internalType":"address"},{"type":"address","name":"gntJoin","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"bytes32","name":"ilk","internalType":"bytes32"},{"type":"uint256","name":"amtC","internalType":"uint256"},{"type":"uint256","name":"wadD","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint256","name":"cdp","internalType":"uint256"}],"name":"openLockGemAndDraw","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"jug","internalType":"address"},{"type":"address","name":"gemJoin","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"bytes32","name":"ilk","internalType":"bytes32"},{"type":"uint256","name":"amtC","internalType":"uint256"},{"type":"uint256","name":"wadD","internalType":"uint256"},{"type":"bool","name":"transferFrom","internalType":"bool"}],"constant":false},{"type":"function","stateMutability":"payable","payable":true,"outputs":[{"type":"uint256","name":"cdp","internalType":"uint256"}],"name":"openLockVLXAndDraw","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"jug","internalType":"address"},{"type":"address","name":"vlxJoin","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"bytes32","name":"ilk","internalType":"bytes32"},{"type":"uint256","name":"wadD","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"quit","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"address","name":"dst","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"safeLockGem","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"gemJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"amt","internalType":"uint256"},{"type":"bool","name":"transferFrom","internalType":"bool"},{"type":"address","name":"owner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"safeLockVLX","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"vlxJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"address","name":"owner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"safeWipe","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"wad","internalType":"uint256"},{"type":"address","name":"owner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"safeWipeAll","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"address","name":"owner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"shift","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"uint256","name":"cdpSrc","internalType":"uint256"},{"type":"uint256","name":"cdpOrg","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transfer","inputs":[{"type":"address","name":"gem","internalType":"address"},{"type":"address","name":"dst","internalType":"address"},{"type":"uint256","name":"amt","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"urnAllow","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"usr","internalType":"address"},{"type":"uint256","name":"ok","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"usdvJoin_join","inputs":[{"type":"address","name":"apt","internalType":"address"},{"type":"address","name":"urn","internalType":"address"},{"type":"uint256","name":"wad","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"vlxJoin_join","inputs":[{"type":"address","name":"apt","internalType":"address"},{"type":"address","name":"urn","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"wipe","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"wad","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"wipeAll","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"wipeAllAndFreeGem","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"gemJoin","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"amtC","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"wipeAllAndFreeVLX","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"vlxJoin","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"wadC","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"wipeAndFreeGem","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"gemJoin","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"amtC","internalType":"uint256"},{"type":"uint256","name":"wadD","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"wipeAndFreeVLX","inputs":[{"type":"address","name":"manager","internalType":"address"},{"type":"address","name":"vlxJoin","internalType":"address"},{"type":"address","name":"usdvJoin","internalType":"address"},{"type":"uint256","name":"cdp","internalType":"uint256"},{"type":"uint256","name":"wadC","internalType":"uint256"},{"type":"uint256","name":"wadD","internalType":"uint256"}],"constant":false}]
            

Deployed ByteCode

0x60806040526004361061023b5760003560e01c806396e8d72c1161012e578063beabacc8116100ab578063db802a321161006f578063db802a3214610c51578063ead6472914610cb9578063eb0b9a8514610d10578063fad2551114610d53578063fba7591d14610d9f5761023b565b8063beabacc814610a9f578063c079171014610ae2578063c96d47fb14610b64578063cbd4be3f14610b9a578063cc1f7ac214610c025761023b565b8063a6add011116100f2578063a6add01114610930578063b50a586914610985578063b6247fdf146109c0578063ba727a9514610a09578063bcd6deec14610a505761023b565b806396e8d72c146107ea5780639f6f3d5b1461082f5780639f887fde1461087e578063a195b561146108b9578063a5aab372146108e75761023b565b8063493c2049116101bc5780636aa3ee11116101805780636aa3ee11146106865780636ab6a491146106db5780637bc3bd53146107245780637df2eb2514610763578063898a09e4146107ae5761023b565b8063493c2049146105105780634b666199146105595780635f6ef447146105a25780636091c3c0146105e5578063696a0fbf1461063a5761023b565b80632958f8a5116102035780632958f8a51461039f578063388bdc7a146103f05780633e29e5651461043357806342dd11bb146104845780634592aca7146104cd5761023b565b8063036a2395146102405780630aee8dec146102855780631558b048146102ce5780631d10f2311461031557806325cf37d014610358575b600080fd5b34801561024c57600080fd5b506102836004803603606081101561026357600080fd5b506001600160a01b03813581169160208101359091169060400135610dee565b005b34801561029157600080fd5b50610283600480360360808110156102a857600080fd5b506001600160a01b038135811691602081013582169160408201359160600135166111aa565b3480156102da57600080fd5b50610283600480360360808110156102f157600080fd5b506001600160a01b0381358116916020810135916040820135169060600135611282565b34801561032157600080fd5b506102836004803603606081101561033857600080fd5b506001600160a01b038135811691602081013591604090910135166112ef565b34801561036457600080fd5b506102836004803603608081101561037b57600080fd5b506001600160a01b038135811691602081013591604082013516906060013561136c565b3480156103ab57600080fd5b50610283600480360360a08110156103c257600080fd5b506001600160a01b0381358116916020810135821691604082013591606081013591608090910135166113c5565b3480156103fc57600080fd5b506102836004803603606081101561041357600080fd5b506001600160a01b0381358116916020810135909116906040013561149f565b34801561043f57600080fd5b50610283600480360360a081101561045657600080fd5b506001600160a01b0381358116916020810135909116906040810135906060810135906080013515156116a5565b34801561049057600080fd5b50610283600480360360808110156104a757600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356118a5565b3480156104d957600080fd5b50610283600480360360608110156104f057600080fd5b506001600160a01b03813581169160208101359160409091013516611908565b34801561051c57600080fd5b506102836004803603608081101561053357600080fd5b506001600160a01b03813581169160208101358216916040820135916060013516611968565b34801561056557600080fd5b506102836004803603608081101561057c57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611b5b565b3480156105ae57600080fd5b50610283600480360360608110156105c557600080fd5b506001600160a01b03813581169160208101359091169060400135611f39565b3480156105f157600080fd5b50610283600480360360c081101561060857600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060808101359060a00135611f99565b610283600480360360c081101561065057600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135612360565b34801561069257600080fd5b506106c9600480360360608110156106a957600080fd5b506001600160a01b0381358116916020810135916040909101351661265a565b60408051918252519081900360200190f35b3480156106e757600080fd5b50610283600480360360808110156106fe57600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356126e1565b34801561073057600080fd5b506102836004803603606081101561074757600080fd5b506001600160a01b038135169060208101359060400135612761565b34801561076f57600080fd5b506102836004803603608081101561078657600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013515156127af565b610283600480360360808110156107c457600080fd5b506001600160a01b038135811691602081013582169160408201359160600135166129bc565b3480156107f657600080fd5b506102836004803603608081101561080d57600080fd5b506001600160a01b038135169060208101359060408101359060600135612a8e565b34801561083b57600080fd5b50610283600480360360a081101561085257600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135612ae4565b34801561088a57600080fd5b50610283600480360360408110156108a157600080fd5b506001600160a01b0381358116916020013516612da5565b610283600480360360408110156108cf57600080fd5b506001600160a01b0381358116916020013516612e19565b3480156108f357600080fd5b506102836004803603608081101561090a57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135612ffe565b34801561093c57600080fd5b50610283600480360360c081101561095357600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060808101359060a00135613174565b34801561099157600080fd5b50610283600480360360408110156109a857600080fd5b506001600160a01b0381358116916020013516613412565b3480156109cc57600080fd5b50610283600480360360808110156109e357600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013561300c565b348015610a1557600080fd5b5061028360048036036080811015610a2c57600080fd5b506001600160a01b038135811691602081013591604082013516906060013561346a565b348015610a5c57600080fd5b50610283600480360360a0811015610a7357600080fd5b506001600160a01b038135811691602081013582169160408201351690606081013590608001356134c3565b348015610aab57600080fd5b5061028360048036036060811015610ac257600080fd5b506001600160a01b03813581169160208101359091169060400135613756565b348015610aee57600080fd5b50610b41600480360360e0811015610b0557600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a08101359060c001356137b6565b604080516001600160a01b03909316835260208301919091528051918290030190f35b61028360048036036060811015610b7a57600080fd5b506001600160a01b03813581169160208101359091169060400135613939565b348015610ba657600080fd5b506102836004803603610100811015610bbe57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a08101359060c08101359060e001351515613b0f565b348015610c0e57600080fd5b50610283600480360360a0811015610c2557600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135613e0c565b348015610c5d57600080fd5b506106c96004803603610100811015610c7557600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a08101359060c08101359060e001351515614187565b348015610cc557600080fd5b50610283600480360360c0811015610cdc57600080fd5b506001600160a01b0381358116916020810135821691604082013591606081013591608082013515159160a00135166141b2565b348015610d1c57600080fd5b5061028360048036036060811015610d3357600080fd5b506001600160a01b03813581169160208101359091169060400135614286565b6106c9600480360360c0811015610d6957600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a001356142e6565b348015610dab57600080fd5b50610dd260048036036020811015610dc257600080fd5b50356001600160a01b031661430d565b604080516001600160a01b039092168252519081900360200190f35b6000836001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610e2957600080fd5b505afa158015610e3d573d6000803e3d6000fd5b505050506040513d6020811015610e5357600080fd5b505160408051632726b07360e01b81526004810185905290519192506000916001600160a01b03871691632726b073916024808301926020929190829003018186803b158015610ea257600080fd5b505afa158015610eb6573d6000803e3d6000fd5b505050506040513d6020811015610ecc57600080fd5b505160408051632c2cb9fd60e01b81526004810186905290519192506000916001600160a01b03881691632c2cb9fd916024808301926020929190829003018186803b158015610f1b57600080fd5b505afa158015610f2f573d6000803e3d6000fd5b505050506040513d6020811015610f4557600080fd5b5051604080516309092f9760e21b8152600481018390526001600160a01b038581166024830152825193945060009390871692632424be5c9260448082019391829003018186803b158015610f9957600080fd5b505afa158015610fad573d6000803e3d6000fd5b505050506040513d6040811015610fc357600080fd5b506020908101516040805163040b0d8960e51b81526004810189905290519193506000926001600160a01b038b1692638161b120926024808201939291829003018186803b15801561101457600080fd5b505afa158015611028573d6000803e3d6000fd5b505050506040513d602081101561103e57600080fd5b505190506001600160a01b0381163014806110db5750604080516302d75da360e51b81526001600160a01b038381166004830152602482018990523060448301529151918a1691635aebb46091606480820192602092909190829003018186803b1580156110ab57600080fd5b505afa1580156110bf573d6000803e3d6000fd5b505050506040513d60208110156110d557600080fd5b50516001145b1561110b576110f687856110f18888898961438a565b61149f565b6111068887600085600003612a8e565b6111a0565b61111c87306110f18830898961438a565b60408051637608870360e01b8152600481018590526001600160a01b0386811660248301523060448301819052606483015260006084830181905285810360a484015292519088169263760887039260c4808201939182900301818387803b15801561118757600080fd5b505af115801561119b573d6000803e3d6000fd5b505050505b5050505050505050565b806001600160a01b0316846001600160a01b0316638161b120846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156111f857600080fd5b505afa15801561120c573d6000803e3d6000fd5b505050506040513d602081101561122257600080fd5b50516001600160a01b031614611271576040805162461bcd60e51b815260206004820152600f60248201526e0deeedccae45adad2e6e6dac2e8c6d608b1b604482015290519081900360640190fd5b61127c848484610dee565b50505050565b604080516313771f0760e31b8152600481018590526001600160a01b03848116602483015260448201849052915191861691639bb8f8389160648082019260009290919082900301818387803b1580156112db57600080fd5b505af11580156111a0573d6000803e3d6000fd5b826001600160a01b031663fcafcc6883836040518363ffffffff1660e01b815260040180838152602001826001600160a01b03166001600160a01b0316815260200192505050600060405180830381600087803b15801561134f57600080fd5b505af1158015611363573d6000803e3d6000fd5b50505050505050565b60408051637cf986db60e11b8152600481018590526001600160a01b0384811660248301526044820184905291519186169163f9f30db69160648082019260009290919082900301818387803b1580156112db57600080fd5b806001600160a01b0316856001600160a01b0316638161b120856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561141357600080fd5b505afa158015611427573d6000803e3d6000fd5b505050506040513d602081101561143d57600080fd5b50516001600160a01b03161461148c576040805162461bcd60e51b815260206004820152600f60248201526e0deeedccae45adad2e6e6dac2e8c6d608b1b604482015290519081900360640190fd5b61149885858585611b5b565b5050505050565b826001600160a01b0316639420069c6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156114da57600080fd5b505af11580156114ee573d6000803e3d6000fd5b505050506040513d602081101561150457600080fd5b5051604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd9160648082019260009290919082900301818387803b15801561155c57600080fd5b505af1158015611570573d6000803e3d6000fd5b50505050826001600160a01b0316639420069c6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156115af57600080fd5b505af11580156115c3573d6000803e3d6000fd5b505050506040513d60208110156115d957600080fd5b50516040805163095ea7b360e01b81526001600160a01b038681166004830152602482018590529151919092169163095ea7b391604480830192600092919082900301818387803b15801561162d57600080fd5b505af1158015611641573d6000803e3d6000fd5b50505050826001600160a01b0316633b4da69f83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561134f57600080fd5b6116b1843084846127af565b846001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156116ea57600080fd5b505afa1580156116fe573d6000803e3d6000fd5b505050506040513d602081101561171457600080fd5b505160408051632c2cb9fd60e01b81526004810186905290516001600160a01b039283169263760887039290891691632c2cb9fd91602480820192602092909190829003018186803b15801561176957600080fd5b505afa15801561177d573d6000803e3d6000fd5b505050506040513d602081101561179357600080fd5b505160408051632726b07360e01b81526004810188905290516001600160a01b038a1691632726b073916024808301926020929190829003018186803b1580156117dc57600080fd5b505afa1580156117f0573d6000803e3d6000fd5b505050506040513d602081101561180657600080fd5b5051308061181c6118178b8a614558565b6145d7565b604080516001600160e01b031960e089901b16815260048101969096526001600160a01b0394851660248701529284166044860152921660648401526084830191909152600060a48301819052905160c48084019382900301818387803b15801561188657600080fd5b505af115801561189a573d6000803e3d6000fd5b505050505050505050565b6118ba8483306118b58786614558565b611282565b6040805163ef693bed60e01b81523360048201526024810183905290516001600160a01b0385169163ef693bed91604480830192600092919082900301818387803b1580156112db57600080fd5b826001600160a01b0316631b0dbf7283836040518363ffffffff1660e01b815260040180838152602001826001600160a01b03166001600160a01b0316815260200192505050600060405180830381600087803b15801561134f57600080fd5b6000846001600160a01b031663c4552791836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156119c057600080fd5b505afa1580156119d4573d6000803e3d6000fd5b505050506040513d60208110156119ea57600080fd5b505190506001600160a01b0381161580611a7a5750816001600160a01b0316816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4257600080fd5b505afa158015611a56573d6000803e3d6000fd5b505050506040513d6020811015611a6c57600080fd5b50516001600160a01b031614155b15611b5057813b8015611ac8576040805162461bcd60e51b8152602060048201526011602482015270111cdd0b5a5ccb584b58dbdb9d1c9858dd607a1b604482015290519081900360640190fd5b856001600160a01b031663f3701da2846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611b2057600080fd5b505af1158015611b34573d6000803e3d6000fd5b505050506040513d6020811015611b4a57600080fd5b50519150505b6114988484836112ef565b6000846001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015611b9657600080fd5b505afa158015611baa573d6000803e3d6000fd5b505050506040513d6020811015611bc057600080fd5b505160408051632726b07360e01b81526004810186905290519192506000916001600160a01b03881691632726b073916024808301926020929190829003018186803b158015611c0f57600080fd5b505afa158015611c23573d6000803e3d6000fd5b505050506040513d6020811015611c3957600080fd5b505160408051632c2cb9fd60e01b81526004810187905290519192506000916001600160a01b03891691632c2cb9fd916024808301926020929190829003018186803b158015611c8857600080fd5b505afa158015611c9c573d6000803e3d6000fd5b505050506040513d6020811015611cb257600080fd5b50516040805163040b0d8960e51b81526004810188905290519192506000916001600160a01b038a1691638161b120916024808301926020929190829003018186803b158015611d0157600080fd5b505afa158015611d15573d6000803e3d6000fd5b505050506040513d6020811015611d2b57600080fd5b505190506001600160a01b038116301480611dc85750604080516302d75da360e51b81526001600160a01b038381166004830152602482018990523060448301529151918a1691635aebb46091606480820192602092909190829003018186803b158015611d9857600080fd5b505afa158015611dac573d6000803e3d6000fd5b505050506040513d6020811015611dc257600080fd5b50516001145b15611e7157611dd887848761149f565b61110688876000611e6c88896001600160a01b03166334b482e58a6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611e3957600080fd5b505afa158015611e4d573d6000803e3d6000fd5b505050506040513d6020811015611e6357600080fd5b50518989614622565b612a8e565b611e7c87308761149f565b836001600160a01b03166376088703838530306000611eaa8b676765c793fa10079d601b1b8e028c8c614622565b6040518763ffffffff1660e01b815260040180878152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018281526020019650505050505050600060405180830381600087803b15801561118757600080fd5b826001600160a01b031663b68f400483836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561134f57600080fd5b6000866001600160a01b0316632726b073856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611fdf57600080fd5b505afa158015611ff3573d6000803e3d6000fd5b505050506040513d602081101561200957600080fd5b5051905061201885828461149f565b6121f88785612026866145d7565b600003611e6c8b6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561206557600080fd5b505afa158015612079573d6000803e3d6000fd5b505050506040513d602081101561208f57600080fd5b5051604080516336569e7760e01b815290516001600160a01b038f16916336569e77916004808301926020929190829003018186803b1580156120d157600080fd5b505afa1580156120e5573d6000803e3d6000fd5b505050506040513d60208110156120fb57600080fd5b5051604080516334b482e560e01b81526001600160a01b038a81166004830152915191909216916334b482e5916024808301926020929190829003018186803b15801561214757600080fd5b505afa15801561215b573d6000803e3d6000fd5b505050506040513d602081101561217157600080fd5b8101908080519060200190929190505050878e6001600160a01b0316632c2cb9fd8d6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156121c757600080fd5b505afa1580156121db573d6000803e3d6000fd5b505050506040513d60208110156121f157600080fd5b5051614622565b61220487853086611282565b6040805163ef693bed60e01b81523060048201526024810185905290516001600160a01b0388169163ef693bed91604480830192600092919082900301818387803b15801561225257600080fd5b505af1158015612266573d6000803e3d6000fd5b50505050856001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156122a557600080fd5b505af11580156122b9573d6000803e3d6000fd5b505050506040513d60208110156122cf57600080fd5b505160408051632e1a7d4d60e01b81526004810186905290516001600160a01b0390921691632e1a7d4d9160248082019260009290919082900301818387803b15801561231b57600080fd5b505af115801561232f573d6000803e3d6000fd5b505060405133925085156108fc02915085906000818181858888f193505050501580156111a0573d6000803e3d6000fd5b6000866001600160a01b0316632726b073846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156123a657600080fd5b505afa1580156123ba573d6000803e3d6000fd5b505050506040513d60208110156123d057600080fd5b5051604080516336569e7760e01b815290519192506000916001600160a01b038a16916336569e77916004808301926020929190829003018186803b15801561241857600080fd5b505afa15801561242c573d6000803e3d6000fd5b505050506040513d602081101561244257600080fd5b505160408051632c2cb9fd60e01b81526004810187905290519192506000916001600160a01b038b1691632c2cb9fd916024808301926020929190829003018186803b15801561249157600080fd5b505afa1580156124a5573d6000803e3d6000fd5b505050506040513d60208110156124bb57600080fd5b505190506124c98784612e19565b6124e489866124d7346145d7565b611e6c868d89888c614758565b6124f88986306124f3886148cf565b61136c565b60408051634538c4eb60e01b81523060048201526001600160a01b038881166024830152915191841691634538c4eb91604480820192602092909190829003018186803b15801561254857600080fd5b505afa15801561255c573d6000803e3d6000fd5b505050506040513d602081101561257257600080fd5b50516125e957816001600160a01b031663a3b22fc4876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b1580156125d057600080fd5b505af11580156125e4573d6000803e3d6000fd5b505050505b6040805163ef693bed60e01b81523360048201526024810186905290516001600160a01b0388169163ef693bed91604480830192600092919082900301818387803b15801561263757600080fd5b505af115801561264b573d6000803e3d6000fd5b50505050505050505050505050565b60408051636090dec560e01b8152600481018490526001600160a01b0383811660248301529151600092861691636090dec591604480830192602092919082900301818787803b1580156126ad57600080fd5b505af11580156126c1573d6000803e3d6000fd5b505050506040513d60208110156126d757600080fd5b5051949350505050565b60006126ed8483614558565b905061270785846126fd846145d7565b6000036000612a8e565b61271385843084611282565b6040805163ef693bed60e01b81523360048201526024810184905290516001600160a01b0386169163ef693bed91604480830192600092919082900301818387803b15801561188657600080fd5b826001600160a01b031663e50322a283836040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561134f57600080fd5b801561295c57836001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156127f057600080fd5b505af1158015612804573d6000803e3d6000fd5b505050506040513d602081101561281a57600080fd5b5051604080516323b872dd60e01b81523360048201523060248201526044810185905290516001600160a01b03909216916323b872dd9160648082019260009290919082900301818387803b15801561287257600080fd5b505af1158015612886573d6000803e3d6000fd5b50505050836001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156128c557600080fd5b505af11580156128d9573d6000803e3d6000fd5b505050506040513d60208110156128ef57600080fd5b50516040805163095ea7b360e01b81526001600160a01b038781166004830152602482018690529151919092169163095ea7b391604480830192600092919082900301818387803b15801561294357600080fd5b505af1158015612957573d6000803e3d6000fd5b505050505b836001600160a01b0316633b4da69f84846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156112db57600080fd5b806001600160a01b0316846001600160a01b0316638161b120846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612a0a57600080fd5b505afa158015612a1e573d6000803e3d6000fd5b505050506040513d6020811015612a3457600080fd5b50516001600160a01b031614612a83576040805162461bcd60e51b815260206004820152600f60248201526e0deeedccae45adad2e6e6dac2e8c6d608b1b604482015290519081900360640190fd5b61127c848484613939565b836001600160a01b03166345e6bdcd8484846040518463ffffffff1660e01b8152600401808481526020018381526020018281526020019350505050600060405180830381600087803b1580156112db57600080fd5b6000856001600160a01b0316632726b073846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612b2a57600080fd5b505afa158015612b3e573d6000803e3d6000fd5b505050506040513d6020811015612b5457600080fd5b5051604080516336569e7760e01b815290519192506000916001600160a01b038916916336569e77916004808301926020929190829003018186803b158015612b9c57600080fd5b505afa158015612bb0573d6000803e3d6000fd5b505050506040513d6020811015612bc657600080fd5b505160408051632c2cb9fd60e01b81526004810187905290519192506000916001600160a01b038a1691632c2cb9fd916024808301926020929190829003018186803b158015612c1557600080fd5b505afa158015612c29573d6000803e3d6000fd5b505050506040513d6020811015612c3f57600080fd5b50519050612c5788866000611e6c868c89888c614758565b612c668886306124f3886148cf565b60408051634538c4eb60e01b81523060048201526001600160a01b038881166024830152915191841691634538c4eb91604480820192602092909190829003018186803b158015612cb657600080fd5b505afa158015612cca573d6000803e3d6000fd5b505050506040513d6020811015612ce057600080fd5b5051612d5757816001600160a01b031663a3b22fc4876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015612d3e57600080fd5b505af1158015612d52573d6000803e3d6000fd5b505050505b6040805163ef693bed60e01b81523360048201526024810186905290516001600160a01b0388169163ef693bed91604480830192600092919082900301818387803b15801561118757600080fd5b816001600160a01b031663dc4d20fa826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015612dfd57600080fd5b505af1158015612e11573d6000803e3d6000fd5b505050505050565b816001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381600087803b158015612e5457600080fd5b505af1158015612e68573d6000803e3d6000fd5b505050506040513d6020811015612e7e57600080fd5b505160408051630d0e30db60e41b815290516001600160a01b039092169163d0e30db0913491600480830192600092919082900301818588803b158015612ec457600080fd5b505af1158015612ed8573d6000803e3d6000fd5b5050505050816001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381600087803b158015612f1857600080fd5b505af1158015612f2c573d6000803e3d6000fd5b505050506040513d6020811015612f4257600080fd5b50516040805163095ea7b360e01b81526001600160a01b0385811660048301523460248301529151919092169163095ea7b391604480830192600092919082900301818387803b158015612f9557600080fd5b505af1158015612fa9573d6000803e3d6000fd5b505060408051633b4da69f60e01b81526001600160a01b03858116600483015234602483015291519186169350633b4da69f925060448082019260009290919082900301818387803b158015612dfd57600080fd5b61300c84836126fd846145d7565b61301884833084611282565b6040805163ef693bed60e01b81523060048201526024810183905290516001600160a01b0385169163ef693bed91604480830192600092919082900301818387803b15801561306657600080fd5b505af115801561307a573d6000803e3d6000fd5b50505050826001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156130b957600080fd5b505af11580156130cd573d6000803e3d6000fd5b505050506040513d60208110156130e357600080fd5b505160408051632e1a7d4d60e01b81526004810184905290516001600160a01b0390921691632e1a7d4d9160248082019260009290919082900301818387803b15801561312f57600080fd5b505af1158015613143573d6000803e3d6000fd5b505060405133925083156108fc02915083906000818181858888f19350505050158015611498573d6000803e3d6000fd5b6000866001600160a01b0316632726b073856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156131ba57600080fd5b505afa1580156131ce573d6000803e3d6000fd5b505050506040513d60208110156131e457600080fd5b505190506131f385828461149f565b60006131ff8785614558565b90506133b8888661320f846145d7565b600003611e6c8c6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561324e57600080fd5b505afa158015613262573d6000803e3d6000fd5b505050506040513d602081101561327857600080fd5b81019080805190602001909291905050508d6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156132c257600080fd5b505afa1580156132d6573d6000803e3d6000fd5b505050506040513d60208110156132ec57600080fd5b5051604080516334b482e560e01b81526001600160a01b038b81166004830152915191909216916334b482e5916024808301926020929190829003018186803b15801561333857600080fd5b505afa15801561334c573d6000803e3d6000fd5b505050506040513d602081101561336257600080fd5b8101908080519060200190929190505050888f6001600160a01b0316632c2cb9fd8e6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156121c757600080fd5b6133c488863084611282565b6040805163ef693bed60e01b81523360048201526024810186905290516001600160a01b0389169163ef693bed91604480830192600092919082900301818387803b15801561118757600080fd5b816001600160a01b031663a3b22fc4826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015612dfd57600080fd5b604080516305b1fdb160e11b8152600481018590526001600160a01b03848116602483015260448201849052915191861691630b63fb629160648082019260009290919082900301818387803b1580156112db57600080fd5b6000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156134fe57600080fd5b505afa158015613512573d6000803e3d6000fd5b505050506040513d602081101561352857600080fd5b505160408051632726b07360e01b81526004810186905290519192506000916001600160a01b03891691632726b073916024808301926020929190829003018186803b15801561357757600080fd5b505afa15801561358b573d6000803e3d6000fd5b505050506040513d60208110156135a157600080fd5b505160408051632c2cb9fd60e01b81526004810187905290519192506000916001600160a01b038a1691632c2cb9fd916024808301926020929190829003018186803b1580156135f057600080fd5b505afa158015613604573d6000803e3d6000fd5b505050506040513d602081101561361a57600080fd5b5051604080516309092f9760e21b8152600481018390526001600160a01b038581166024830152825193945060009390871692632424be5c9260448082019391829003018186803b15801561366e57600080fd5b505afa158015613682573d6000803e3d6000fd5b505050506040513d604081101561369857600080fd5b506020015190506136b087846110f18782808861438a565b60006136bc8987614558565b90506136d88a886136cc846145d7565b60000385600003612a8e565b6136e48a883084611282565b6040805163ef693bed60e01b81523360048201526024810188905290516001600160a01b038b169163ef693bed91604480830192600092919082900301818387803b15801561373257600080fd5b505af1158015613746573d6000803e3d6000fd5b5050505050505050505050505050565b826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561134f57600080fd5b60408051638c4c280160e01b8152306004820152905160009182916001600160a01b03891691638c4c2801916024808301926020929190829003018186803b15801561380157600080fd5b505afa158015613815573d6000803e3d6000fd5b505050506040513d602081101561382b57600080fd5b505191506001600160a01b038216613849576138468761430d565b91505b866001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561388457600080fd5b505af1158015613898573d6000803e3d6000fd5b505050506040513d60208110156138ae57600080fd5b50516040805163a9059cbb60e01b81526001600160a01b038581166004830152602482018890529151919092169163a9059cbb91604480830192600092919082900301818387803b15801561390257600080fd5b505af1158015613916573d6000803e3d6000fd5b5050505061392b898989898989896000614187565b905097509795505050505050565b6139438230612e19565b826001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561397c57600080fd5b505afa158015613990573d6000803e3d6000fd5b505050506040513d60208110156139a657600080fd5b505160408051632c2cb9fd60e01b81526004810184905290516001600160a01b039283169263760887039290871691632c2cb9fd91602480820192602092909190829003018186803b1580156139fb57600080fd5b505afa158015613a0f573d6000803e3d6000fd5b505050506040513d6020811015613a2557600080fd5b505160408051632726b07360e01b81526004810186905290516001600160a01b03881691632726b073916024808301926020929190829003018186803b158015613a6e57600080fd5b505afa158015613a82573d6000803e3d6000fd5b505050506040513d6020811015613a9857600080fd5b50513080613aa5346145d7565b604080516001600160e01b031960e089901b16815260048101969096526001600160a01b0394851660248701529284166044860152921660648401526084830191909152600060a48301819052905160c48084019382900301818387803b15801561134f57600080fd5b6000886001600160a01b0316632726b073866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015613b5557600080fd5b505afa158015613b69573d6000803e3d6000fd5b505050506040513d6020811015613b7f57600080fd5b5051604080516336569e7760e01b815290519192506000916001600160a01b038c16916336569e77916004808301926020929190829003018186803b158015613bc757600080fd5b505afa158015613bdb573d6000803e3d6000fd5b505050506040513d6020811015613bf157600080fd5b505160408051632c2cb9fd60e01b81526004810189905290519192506000916001600160a01b038d1691632c2cb9fd916024808301926020929190829003018186803b158015613c4057600080fd5b505afa158015613c54573d6000803e3d6000fd5b505050506040513d6020811015613c6a57600080fd5b50519050613c7a898488876127af565b613c998b88613c8c6118178d8b614558565b611e6c868f89888d614758565b613ca88b88306124f3896148cf565b60408051634538c4eb60e01b81523060048201526001600160a01b038a81166024830152915191841691634538c4eb91604480820192602092909190829003018186803b158015613cf857600080fd5b505afa158015613d0c573d6000803e3d6000fd5b505050506040513d6020811015613d2257600080fd5b5051613d9957816001600160a01b031663a3b22fc4896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015613d8057600080fd5b505af1158015613d94573d6000803e3d6000fd5b505050505b6040805163ef693bed60e01b81523360048201526024810187905290516001600160a01b038a169163ef693bed91604480830192600092919082900301818387803b158015613de757600080fd5b505af1158015613dfb573d6000803e3d6000fd5b505050505050505050505050505050565b6000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015613e4757600080fd5b505afa158015613e5b573d6000803e3d6000fd5b505050506040513d6020811015613e7157600080fd5b505160408051632726b07360e01b81526004810186905290519192506000916001600160a01b03891691632726b073916024808301926020929190829003018186803b158015613ec057600080fd5b505afa158015613ed4573d6000803e3d6000fd5b505050506040513d6020811015613eea57600080fd5b505160408051632c2cb9fd60e01b81526004810187905290519192506000916001600160a01b038a1691632c2cb9fd916024808301926020929190829003018186803b158015613f3957600080fd5b505afa158015613f4d573d6000803e3d6000fd5b505050506040513d6020811015613f6357600080fd5b5051604080516309092f9760e21b8152600481018390526001600160a01b038581166024830152825193945060009390871692632424be5c9260448082019391829003018186803b158015613fb757600080fd5b505afa158015613fcb573d6000803e3d6000fd5b505050506040513d6040811015613fe157600080fd5b50602001519050613ff987846110f18782808861438a565b6140138987614007886145d7565b60000384600003612a8e565b61401f89873088611282565b6040805163ef693bed60e01b81523060048201526024810187905290516001600160a01b038a169163ef693bed91604480830192600092919082900301818387803b15801561406d57600080fd5b505af1158015614081573d6000803e3d6000fd5b50505050876001600160a01b0316637bd2bea76040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156140c057600080fd5b505af11580156140d4573d6000803e3d6000fd5b505050506040513d60208110156140ea57600080fd5b505160408051632e1a7d4d60e01b81526004810188905290516001600160a01b0390921691632e1a7d4d9160248082019260009290919082900301818387803b15801561413657600080fd5b505af115801561414a573d6000803e3d6000fd5b505060405133925087156108fc02915087906000818181858888f1935050505015801561417b573d6000803e3d6000fd5b50505050505050505050565b600061419489863061265a565b90506141a68989898985898989613b0f565b98975050505050505050565b806001600160a01b0316866001600160a01b0316638161b120866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561420057600080fd5b505afa158015614214573d6000803e3d6000fd5b505050506040513d602081101561422a57600080fd5b50516001600160a01b031614614279576040805162461bcd60e51b815260206004820152600f60248201526e0deeedccae45adad2e6e6dac2e8c6d608b1b604482015290519081900360640190fd5b612e1186868686866116a5565b826001600160a01b0316637e348b7d83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561134f57600080fd5b60006142f387843061265a565b9050614303878787878587612360565b9695505050505050565b60408051631060930d60e01b815230600482015290516000916001600160a01b03841691631060930d9160248082019260209290919082900301818787803b15801561435857600080fd5b505af115801561436c573d6000803e3d6000fd5b505050506040513d602081101561438257600080fd5b505192915050565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b81526004018082815260200191505060a06040518083038186803b1580156143d157600080fd5b505afa1580156143e5573d6000803e3d6000fd5b505050506040513d60a08110156143fb57600080fd5b5060200151604080516309092f9760e21b8152600481018690526001600160a01b0387811660248301528251939450600093908a1692632424be5c9260448082019391829003018186803b15801561445257600080fd5b505afa158015614466573d6000803e3d6000fd5b505050506040513d604081101561447c57600080fd5b50602090810151604080516334b482e560e01b81526001600160a01b038a811660048301529151929450600093918b16926334b482e592602480840193919291829003018186803b1580156144d057600080fd5b505afa1580156144e4573d6000803e3d6000fd5b505050506040513d60208110156144fa57600080fd5b50519050600061451361450d84866148ec565b83614947565b9050676765c793fa10079d601b1b810494508061453b86676765c793fa10079d601b1b6148ec565b10614546578461454b565b846001015b9998505050505050505050565b60006145d082846001600160a01b031663b3bcfa826040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561459957600080fd5b505af11580156145ad573d6000803e3d6000fd5b505050506040513d60208110156145c357600080fd5b5051601203600a0a6148ec565b9392505050565b80600081121561461d576040805162461bcd60e51b815260206004820152600c60248201526b696e742d6f766572666c6f7760a01b604482015290519081900360640190fd5b919050565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b81526004018082815260200191505060a06040518083038186803b15801561466957600080fd5b505afa15801561467d573d6000803e3d6000fd5b505050506040513d60a081101561469357600080fd5b5060200151604080516309092f9760e21b8152600481018690526001600160a01b0387811660248301528251939450600093908a1692632424be5c9260448082019391829003018186803b1580156146ea57600080fd5b505afa1580156146fe573d6000803e3d6000fd5b505050506040513d604081101561471457600080fd5b5060200151905061472d82878161472757fe5b046145d7565b92508083111561474857614740816145d7565b60000361474d565b826000035b979650505050505050565b600080856001600160a01b03166344e2a5a8856040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156147a157600080fd5b505af11580156147b5573d6000803e3d6000fd5b505050506040513d60208110156147cb57600080fd5b5051604080516334b482e560e01b81526001600160a01b0388811660048301529151929350600092918a16916334b482e591602480820192602092909190829003018186803b15801561481d57600080fd5b505afa158015614831573d6000803e3d6000fd5b505050506040513d602081101561484757600080fd5b5051905061486084676765c793fa10079d601b1b6148ec565b8110156148c4576148908261488961488387676765c793fa10079d601b1b6148ec565b84614947565b8161472757fe5b92506148a784676765c793fa10079d601b1b6148ec565b6148b184846148ec565b106148bc57826148c1565b826001015b92505b505095945050505050565b60006148e682676765c793fa10079d601b1b6148ec565b92915050565b60008115806149075750508082028282828161490457fe5b04145b6148e6576040805162461bcd60e51b815260206004820152600c60248201526b6d756c2d6f766572666c6f7760a01b604482015290519081900360640190fd5b808203828111156148e6576040805162461bcd60e51b815260206004820152600c60248201526b7375622d6f766572666c6f7760a01b604482015290519081900360640190fdfea265627a7a72315820f3835689cca96481316b799aa3802c94f0a5510441716a4b4bfffd58d849d79e64736f6c634300050c0032