{"file_path":"PegKeeperRegulator.vy","creation_status":"success","source_code":"# @version 0.3.10\n\"\"\"\n@title Peg Keeper Regulator\n@author Curve.Fi\n@notice Regulations for Peg Keeper\n@license MIT\n\"\"\"\n\ninterface ERC20:\n    def balanceOf(_owner: address) -> uint256: view\n\ninterface StableSwap:\n    def get_p(i: uint256=0) -> uint256: view\n    def price_oracle(i: uint256=0) -> uint256: view\n\ninterface PegKeeper:\n    def pool() -> StableSwap: view\n    def debt() -> uint256: view\n    def IS_INVERSE() -> bool: view\n\ninterface Aggregator:\n    def price() -> uint256: view\n    def price_w() -> uint256: nonpayable\n\nevent AddPegKeeper:\n    peg_keeper: PegKeeper\n    pool: StableSwap\n    is_inverse: bool\n\nevent RemovePegKeeper:\n    peg_keeper: PegKeeper\n\nevent WorstPriceThreshold:\n    threshold: uint256\n\nevent PriceDeviation:\n    price_deviation: uint256\n\nevent DebtParameters:\n    alpha: uint256\n    beta: uint256\n\nevent SetAggregator:\n    aggregator: address\n\nevent SetFeeReceiver:\n    fee_receiver: address\n\nevent SetKilled:\n    is_killed: Killed\n    by: address\n\nevent SetAdmin:\n    admin: address\n\nevent SetEmergencyAdmin:\n    admin: address\n\nstruct PegKeeperInfo:\n    peg_keeper: PegKeeper\n    pool: StableSwap\n    is_inverse: bool\n    include_index: bool\n\nenum Killed:\n    Provide  # 1\n    Withdraw  # 2\n\nMAX_LEN: constant(uint256) = 8\nONE: constant(uint256) = 10 ** 18\n\nworst_price_threshold: public(uint256)\nprice_deviation: public(uint256)\nalpha: public(uint256)  # Initial boundary\nbeta: public(uint256)  # Each PegKeeper's impact\n\nSTABLECOIN: immutable(ERC20)\naggregator: public(Aggregator)\npeg_keepers: public(DynArray[PegKeeperInfo, MAX_LEN])\npeg_keeper_i: HashMap[PegKeeper,  uint256]  # 1 + index of peg keeper in a list\n\nfee_receiver: public(address)\n\nis_killed: public(Killed)\nadmin: public(address)\nemergency_admin: public(address)\n\n\n@external\ndef __init__(_stablecoin: ERC20, _agg: Aggregator, _fee_receiver: address, _admin: address, _emergency_admin: address):\n    STABLECOIN = _stablecoin\n    self.aggregator = _agg\n    self.fee_receiver = _fee_receiver\n    self.admin = _admin\n    self.emergency_admin = _emergency_admin\n    log SetAdmin(_admin)\n    log SetEmergencyAdmin(_emergency_admin)\n\n    self.worst_price_threshold = 3 * 10 ** (18 - 4)  # 0.0003\n    self.price_deviation = 5 * 10 ** (18 - 4) # 0.0005 = 0.05%\n    self.alpha = ONE / 2 # 1/2\n    self.beta = ONE / 4  # 1/4\n    log WorstPriceThreshold(self.worst_price_threshold)\n    log PriceDeviation(self.price_deviation)\n    log DebtParameters(self.alpha, self.beta)\n\n\n@external\n@view\ndef stablecoin() -> ERC20:\n    return STABLECOIN\n\n\n@internal\n@pure\ndef _get_price(_info: PegKeeperInfo) -> uint256:\n    \"\"\"\n    @return Price of the coin in STABLECOIN\n    \"\"\"\n    price: uint256 = 0\n    if _info.include_index:\n        price = _info.pool.get_p(0)\n    else:\n        price = _info.pool.get_p()\n    if _info.is_inverse:\n        price = 10 ** 36 / price\n    return price\n\n\n@internal\n@pure\ndef _get_price_oracle(_info: PegKeeperInfo) -> uint256:\n    \"\"\"\n    @return Price of the coin in STABLECOIN\n    \"\"\"\n    price: uint256 = 0\n    if _info.include_index:\n        price = _info.pool.price_oracle(0)\n    else:\n        price = _info.pool.price_oracle()\n    if _info.is_inverse:\n        price = 10 ** 36 / price\n    return price\n\n\n@internal\n@view\ndef _price_in_range(_p0: uint256, _p1: uint256) -> bool:\n    \"\"\"\n    @notice Check that the price is in accepted range using absolute error\n    @dev Needed for spam-attack protection\n    \"\"\"\n    # |p1 - p0| <= deviation\n    # -deviation <= p1 - p0 <= deviation\n    # 0 < deviation + p1 - p0 <= 2 * deviation\n    # can use unsafe\n    deviation: uint256 = self.price_deviation\n    return unsafe_sub(unsafe_add(deviation, _p0), _p1) < deviation << 1\n\n\n@internal\n@view\ndef _get_ratio(_peg_keeper: PegKeeper) -> uint256:\n    \"\"\"\n    @return debt ratio limited up to 1\n    \"\"\"\n    debt: uint256 = _peg_keeper.debt()\n    return debt * ONE / (1 + debt + STABLECOIN.balanceOf(_peg_keeper.address))\n\n\n@internal\n@view\ndef _get_max_ratio(_debt_ratios: DynArray[uint256, MAX_LEN]) -> uint256:\n    rsum: uint256 = 0\n    for r in _debt_ratios:\n        rsum += isqrt(r * ONE)\n    return (self.alpha + self.beta * rsum / ONE) ** 2 / ONE\n\n\n@external\n@view\ndef provide_allowed(_pk: address=msg.sender) -> uint256:\n    \"\"\"\n    @notice Allow PegKeeper to provide stablecoin into the pool\n    @dev Can return more amount than available\n    @dev Checks\n        1) current price in range of oracle in case of spam-attack\n        2) current price location among other pools in case of contrary coin depeg\n        3) stablecoin price is above 1\n    @return Amount of stablecoin allowed to provide\n    \"\"\"\n    if self.is_killed in Killed.Provide:\n        return 0\n\n    if self.aggregator.price() < ONE:\n        return 0\n\n    price: uint256 = max_value(uint256)  # Will fail if PegKeeper is not in self.price_pairs\n    largest_price: uint256 = 0\n    debt_ratios: DynArray[uint256, MAX_LEN] = []\n    for info in self.peg_keepers:\n        price_oracle: uint256 = self._get_price_oracle(info)\n        if info.peg_keeper.address == _pk:\n            price = price_oracle\n            if not self._price_in_range(price, self._get_price(info)):\n                return 0\n            continue\n        elif largest_price < price_oracle:\n            largest_price = price_oracle\n        debt_ratios.append(self._get_ratio(info.peg_keeper))\n\n    if largest_price < unsafe_sub(price, self.worst_price_threshold):\n        return 0\n\n    debt: uint256 = PegKeeper(_pk).debt()\n    total: uint256 = debt + STABLECOIN.balanceOf(_pk)\n    return self._get_max_ratio(debt_ratios) * total / ONE - debt\n\n\n\n@external\n@view\ndef withdraw_allowed(_pk: address=msg.sender) -> uint256:\n    \"\"\"\n    @notice Allow Peg Keeper to withdraw stablecoin from the pool\n    @dev Can return more amount than available\n    @dev Checks\n        1) current price in range of oracle in case of spam-attack\n        2) stablecoin price is below 1\n    @return Amount of stablecoin allowed to withdraw\n    \"\"\"\n    if self.is_killed in Killed.Withdraw:\n        return 0\n\n    if self.aggregator.price() > ONE:\n        return 0\n\n    i: uint256 = self.peg_keeper_i[PegKeeper(_pk)]\n    if i > 0:\n        info: PegKeeperInfo = self.peg_keepers[i - 1]\n        if self._price_in_range(self._get_price(info), self._get_price_oracle(info)):\n            return max_value(uint256)\n    return 0\n\n\n@external\ndef add_peg_keepers(_peg_keepers: DynArray[PegKeeper, MAX_LEN]):\n    assert msg.sender == self.admin\n\n    i: uint256 = len(self.peg_keepers)\n    for pk in _peg_keepers:\n        assert self.peg_keeper_i[pk] == empty(uint256)  # dev: duplicate\n        pool: StableSwap = pk.pool()\n        success: bool = raw_call(\n            pool.address, _abi_encode(convert(0, uint256), method_id=method_id(\"price_oracle(uint256)\")),\n            revert_on_failure=False\n        )\n        info: PegKeeperInfo = PegKeeperInfo({\n            peg_keeper: pk,\n            pool: pool,\n            is_inverse: pk.IS_INVERSE(),\n            include_index: success,\n        })\n        self.peg_keepers.append(info)  # dev: too many pairs\n        i += 1\n        self.peg_keeper_i[pk] = i\n\n        log AddPegKeeper(info.peg_keeper, info.pool, info.is_inverse)\n\n\n@external\ndef remove_peg_keepers(_peg_keepers: DynArray[PegKeeper, MAX_LEN]):\n    \"\"\"\n    @dev Most gas efficient will be sort pools reversely\n    \"\"\"\n    assert msg.sender == self.admin\n\n    peg_keepers: DynArray[PegKeeperInfo, MAX_LEN] = self.peg_keepers\n    for pk in _peg_keepers:\n        i: uint256 = self.peg_keeper_i[pk] - 1  # dev: pool not found\n        max_n: uint256 = len(peg_keepers) - 1\n        if i < max_n:\n            peg_keepers[i] = peg_keepers[max_n]\n            self.peg_keeper_i[peg_keepers[i].peg_keeper] = 1 + i\n\n        peg_keepers.pop()\n        self.peg_keeper_i[pk] = empty(uint256)\n        log RemovePegKeeper(pk)\n\n    self.peg_keepers = peg_keepers\n\n\n@external\ndef set_worst_price_threshold(_threshold: uint256):\n    \"\"\"\n    @notice Set threshold for the worst price that is still accepted\n    @param _threshold Price threshold with base 10 ** 18 (1.0 = 10 ** 18)\n    \"\"\"\n    assert msg.sender == self.admin\n    assert _threshold <= 10 ** (18 - 2)  # 0.01\n    self.worst_price_threshold = _threshold\n    log WorstPriceThreshold(_threshold)\n\n\n@external\ndef set_price_deviation(_deviation: uint256):\n    \"\"\"\n    @notice Set acceptable deviation of current price from oracle's\n    @param _deviation Deviation of price with base 10 ** 18 (1.0 = 10 ** 18)\n    \"\"\"\n    assert msg.sender == self.admin\n    assert _deviation <= 10 ** 20\n    self.price_deviation = _deviation\n    log PriceDeviation(_deviation)\n\n\n@external\ndef set_debt_parameters(_alpha: uint256, _beta: uint256):\n    \"\"\"\n    @notice Set parameters for calculation of debt limits\n    @dev 10 ** 18 precision\n    \"\"\"\n    assert msg.sender == self.admin\n    assert _alpha <= ONE\n    assert _beta <= ONE\n\n    self.alpha = _alpha\n    self.beta = _beta\n    log DebtParameters(_alpha, _beta)\n\n\n@external\ndef set_aggregator(_agg: Aggregator):\n    \"\"\"\n    @notice Set new crvUSD price aggregator\n    \"\"\"\n    assert msg.sender == self.admin\n    self.aggregator = _agg\n    log SetAggregator(_agg.address)\n\n\n@external\ndef set_fee_receiver(_fee_receiver: address):\n    \"\"\"\n    @notice Set new PegKeeper's profit receiver\n    \"\"\"\n    assert msg.sender == self.admin\n    self.fee_receiver = _fee_receiver\n    log SetFeeReceiver(_fee_receiver)\n\n\n@external\ndef set_killed(_is_killed: Killed):\n    \"\"\"\n    @notice Pause/unpause Peg Keepers\n    @dev 0 unpause, 1 provide, 2 withdraw, 3 everything\n    \"\"\"\n    assert msg.sender in [self.admin, self.emergency_admin]\n    self.is_killed = _is_killed\n    log SetKilled(_is_killed, msg.sender)\n\n\n@external\ndef set_admin(_admin: address):\n    # We are not doing commit / apply because the owner will be a voting DAO anyway\n    # which has vote delays\n    assert msg.sender == self.admin\n    self.admin = _admin\n    log SetAdmin(_admin)\n\n\n@external\ndef set_emergency_admin(_admin: address):\n    assert msg.sender == self.admin\n    self.emergency_admin = _admin\n    log SetEmergencyAdmin(_admin)","deployed_bytecode":"0x5f3560e01c60026016820660011b61127001601e395f51565b635912fb7a8118610e84573461126c575f5460405260206040f3610e84565b63187fae818118610e84573461126c5760015460405260206040f3610e84565b63db1d0fd58118610073573461126c5760025460405260206040f35b634476d2bb81186103935760243610341761126c576004358060a01c61126c576101a0525b600160285416156100b2575f6101c05260206101c0610391565b670de0b6b3a763ffff60045463a035b1fe6101c05260206101c060046101dc845afa6100e0573d5f5f3e3d5ffd5b60203d1061126c576101c090505111610102575f610200526020610200610391565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101c0526040366101e0375f6005546008811161126c57801561027757905b8060021b600601805461032052600181015461034052600281015461036052600381015461038052506103205160405261034051606052610360516080526103805160a0526101926103c0610f33565b6103c0516103a0526101a0516103205118610220576103a0516101c0526101c051610400526103205160405261034051606052610360516080526103805160a0526101de6103c0610e88565b6103c0516104205261040051604052610420516060526101ff6103e0610fde565b6103e05161026c5750505f6104405260206104406103915661026c56610237565b6103a0516101e0511015610237576103a0516101e0525b610200516007811161126c57610320516040526102556103c0610ffb565b6103c0518160051b61022001526001810161020052505b600101818118610142575b50505f546101c051036101e0511015610299575f610320526020610320610391565b6101a051630dca59c1610340526020610340600461035c845afa6102bf573d5f5f3e3d5ffd5b60203d1061126c576103409050516103205261032051602061129c5f395f516370a08231610360526101a051610380526020610360602461037c845afa610308573d5f5f3e3d5ffd5b60203d1061126c5761036090505180820182811061126c5790509050610340526102005160208160051b018060408261020060045afa50505061034c6103606110ba565b610360516103405180820281158383830414171561126c5790509050670de0b6b3a7640000810490506103205180820382811161126c57905090506103805260206103805bf35b633278d11f8118610e84573461126c5733610120526105fe56610e84565b639faa3c9181186103cd573461126c5760035460405260206040f35b63813111ab8118610e845760443610341761126c57602954331861126c57670de0b6b3a76400006004351161126c57670de0b6b3a76400006024351161126c576004356002556024356003557f069906c4131a2e2c0b2f32f351644b280d95237fa3f095f91ac69cac88ab92346040600460403760406040a100610e84565b63245a7bfc8118610468573461126c5760045460405260206040f35b633ad799aa81186104c95760243610341761126c57602954331861126c57662386f26fc100006004351161126c576004355f557fb4a3856a5d3f85a0db622badf557a5c47e98ef4ce2f9fced462328721ee80c7660043560405260206040a1005b634fc6286a8118610e845760243610341761126c57602954331861126c5768056bc75e2d631000006004351161126c576004356001557f406e5474c6819832e7834a919ce48a8c8d909e2d9a3a0fe5378844c3b51b46a260043560405260206040a100610e84565b63f6235138811861057d5760243610341761126c5760043560055481101561126c5760021b600601805460405260018101546060526002810154608052600381015460a0525060806040f35b639c868ac08118610e84573461126c5760285460405260206040f3610e84565b63cab4d3db8118610e84573461126c5760275460405260206040f3610e84565b63f851a44081186105d9573461126c5760295460405260206040f35b63990ca2b08118610e845760243610341761126c576004358060a01c61126c57610120525b60026028541615610618575f610140526020610140610782565b670de0b6b3a764000160045463a035b1fe610140526020610140600461015c845afa610646573d5f5f3e3d5ffd5b60203d1061126c5761014090505110610668575f610180526020610180610782565b6026610120516020525f5260405f205461014052610140511561077757610140516001810381811161126c57905060055481101561126c5760021b60060180546101605260018101546101805260028101546101a05260038101546101c0525061016051604052610180516060526101a0516080526101c05160a0526106ef6101e0610e88565b6101e0516102405261016051604052610180516060526101a0516080526101c05160a05261071e610200610f33565b6102005161026052610240516040526102605160605261073f610220610fde565b6102205115610777577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610280526020610280610782565b5f6101605260206101605bf3610e84565b63680c77838118610e84573461126c57602a5460405260206040f3610e84565b63e9cbd82281186107c6573461126c57602061129c60403960206040f35b637717b58c8118610e845760443610341761126c57600435600401600881351161126c5780355f816008811161126c57801561082357905b8060051b6020850101358060a01c61126c578160051b606001526001018181186107fe575b5050806040525050602954331861126c5760055460208160071b015f81601f0160051c6021811161126c57801561086f57905b80600501548160051b6101600152600101818118610856575b505050505f6040516008811161126c5780156109db57905b8060051b60600151610580526026610580516020525f5260405f20546001810381811161126c5790506105a052610160516001810381811161126c5790506105c0526105c0516105a051101561097d576105c0516101605181101561126c5760071b6101800180516105e052602081015161060052604081015161062052606081015161064052506105a0516101605181101561126c5760071b610180016105e0518152610600516020820152610620516040820152610640516060820152506105a051806001016001811061126c57905060266105a0516101605181101561126c5760071b61018001516020525f5260405f20555b600161016051801561126c57038061016052505f6026610580516020525f5260405f20557f52182c3057b74a074adcacf89ba9ff9860a1265c89cfecd998a111e06bc80267610580516105e05260206105e0a1600101818118610887575b50506101605160208160071b015f81601f0160051c6021811161126c578015610a1957905b8060051b61016001518160050155600101818118610a00575b5050505000610e84565b6324039e728118610a3d573461126c57336101a052610098565b63aa7c366c8118610e845760243610341761126c576004358060021c61126c57604052336029548118610a71576001610a78565b602a548118155b90501561126c576040516028557f4f68ba80bc10140c2ec9990a643fe65220bf8b240f8da93df41290bceee79cd26040516060523360805260406060a100610e84565b63b3a6ace48118610e845760443610341761126c57600435600401600881351161126c5780355f816008811161126c578015610b1857905b8060051b6020850101358060a01c61126c578160051b60600152600101818118610af3575b5050806040525050602954331861126c57600554610160525f6040516008811161126c578015610cf057905b8060051b60600151610180526026610180516020525f5260405f205461126c57610180516316f0115b6101c05260206101c060046101dc845afa610b8a573d5f5f3e3d5ffd5b60203d1061126c576101c0518060a01c61126c57610200526102009050516101a0526101a0515a63687276536101e45260045f610204526020016101e0526101e0505f5f6101e0516102005f8686f1905090506101c052610180516101e0526101a051610200526101805163f96b9f18610260526020610260600461027c845afa610c17573d5f5f3e3d5ffd5b60203d1061126c57610260518060011c61126c576102a0526102a0905051610220526101c051610240526005546007811161126c578060021b6006016101e0518155610200516001820155610220516002820155610240516003820155506001810160055550610160516001810181811061126c57905061016052610160516026610180516020525f5260405f20557f16258839d7d9de7d5af567f0f747bb55d4b7a8fb7d125b7c3d55f5e5f573a6806101e051610260526102005161028052610220516102a0526060610260a1600101818118610b44575b505000610e84565b634c2cf2cd8118610e845760243610341761126c576004358060a01c61126c57604052602954331861126c576040516004557fe3019176e17c666cf4037ff4eaf90f47c7eaa9d7445cac6c1577d7a6fb903b8f60405160605260206060a100610e84565b63e41ab7718118610e845760243610341761126c576004358060a01c61126c57604052602954331861126c576040516027557fffb40bfdfd246e95f543d08d9713c339f1d90fa9265e39b4f562f9011d7c919f60405160605260206060a100610e84565b63e9333fab8118610e845760243610341761126c576004358060a01c61126c57604052602954331861126c576040516029557f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a160405160605260206060a100610e84565b6380b6d8028118610e845760243610341761126c576004358060a01c61126c57604052602954331861126c57604051602a557fb72d36542c9b761c0d9b215bddd7b59c055dd4fb2f6c5da22e964720458ddff160405160605260206060a1005b5f5ffd5b5f60c05260a051610eca5760605163f2388acb60e052602060e0600460fc845afa610eb5573d5f5f3e3d5ffd5b60203d1061126c5760e090505160c052610f02565b60605163ec02386260e0525f61010052602060e0602460fc845afa610ef1573d5f5f3e3d5ffd5b60203d1061126c5760e090505160c0525b60805115610f2b5760c051801561126c57806ec097ce7bc90715b34b9f100000000004905060c0525b60c051815250565b5f60c05260a051610f75576060516386fc88d360e052602060e0600460fc845afa610f60573d5f5f3e3d5ffd5b60203d1061126c5760e090505160c052610fad565b606051636872765360e0525f61010052602060e0602460fc845afa610f9c573d5f5f3e3d5ffd5b60203d1061126c5760e090505160c0525b60805115610fd65760c051801561126c57806ec097ce7bc90715b34b9f100000000004905060c0525b60c051815250565b60015460805260805160011b606051604051608051010310815250565b604051630dca59c1608052602060806004609c845afa61101d573d5f5f3e3d5ffd5b60203d1061126c576080905051606052606051670de0b6b3a7640000810281670de0b6b3a764000082041861126c579050606051806001016001811061126c579050602061129c5f395f516370a0823160805260405160a052602060806024609c845afa61108d573d5f5f3e3d5ffd5b60203d1061126c57608090505180820182811061126c5790509050801561126c5780820490509050815250565b5f610160525f6040516008811161126c57801561120257905b8060051b60600151610180526101605161018051670de0b6b3a7640000810281670de0b6b3a764000082041861126c5790508060b571010000000000000000000000000000000000821061112e578160801c91508060401b90505b6901000000000000000000821061114c578160401c91508060201b90505b650100000000008210611166578160201c91508060101b90505b6301000000821061117e578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808304808281188284100218905090509050905080820182811061126c5790509050610160526001018181186110d3575b50506002546003546101605180820281158383830414171561126c5790509050670de0b6b3a76400008104905080820182811061126c57905090506fffffffffffffffffffffffffffffffff811161126c576002810a9050670de0b6b3a764000081049050815250565b5f80fd07a80d5c0e240e840e84078805bd0e8400180e840e8400370e840cf80a230dc0044c059d053100570abb03b1000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"outputSelection":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]},"search_paths":["."]},"optimization_runs":null,"sourcify_repo_url":null,"decoded_constructor_args":[["0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E",{"name":"_stablecoin","type":"address"}],["0x18672b1b0c623a30089A280Ed9256379fb0E4E62",{"name":"_agg","type":"address"}],["0xeCb456EA5365865EbAb8a2661B0c503410e9B347",{"name":"_fee_receiver","type":"address"}],["0x40907540d8a6C65c637785e8f8B742ae6b0b9968",{"name":"_admin","type":"address"}],["0x00669DF67E4827FCc0E48A1838a8d5AB79281909",{"name":"_emergency_admin","type":"address"}]],"compiler_version":"v0.3.10+commit.91361694","is_verified_via_verifier_alliance":false,"verified_at":"2026-01-15T02:18:43.591820Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x61129c5150346101ad5760206114635f395f518060a01c6101ad5760405260206114835f395f518060a01c6101ad5760605260206114a35f395f518060a01c6101ad5760805260206114c35f395f518060a01c6101ad5760a05260206114e35f395f518060a01c6101ad5760c05260405161129c5260605160045560805160275560a05160295560c051602a557f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a160a05160e052602060e0a17fb72d36542c9b761c0d9b215bddd7b59c055dd4fb2f6c5da22e964720458ddff160c05160e052602060e0a1660110d9316ec0005f556601c6bf526340006001556706f05b59d3b200006002556703782dace9d900006003557fb4a3856a5d3f85a0db622badf557a5c47e98ef4ce2f9fced462328721ee80c765f5460e052602060e0a17f406e5474c6819832e7834a919ce48a8c8d909e2d9a3a0fe5378844c3b51b46a260015460e052602060e0a17f069906c4131a2e2c0b2f32f351644b280d95237fa3f095f91ac69cac88ab923460025460e05260035461010052604060e0a161129c6101b1610000396112bc610000f35b5f80fd5f3560e01c60026016820660011b61127001601e395f51565b635912fb7a8118610e84573461126c575f5460405260206040f3610e84565b63187fae818118610e84573461126c5760015460405260206040f3610e84565b63db1d0fd58118610073573461126c5760025460405260206040f35b634476d2bb81186103935760243610341761126c576004358060a01c61126c576101a0525b600160285416156100b2575f6101c05260206101c0610391565b670de0b6b3a763ffff60045463a035b1fe6101c05260206101c060046101dc845afa6100e0573d5f5f3e3d5ffd5b60203d1061126c576101c090505111610102575f610200526020610200610391565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101c0526040366101e0375f6005546008811161126c57801561027757905b8060021b600601805461032052600181015461034052600281015461036052600381015461038052506103205160405261034051606052610360516080526103805160a0526101926103c0610f33565b6103c0516103a0526101a0516103205118610220576103a0516101c0526101c051610400526103205160405261034051606052610360516080526103805160a0526101de6103c0610e88565b6103c0516104205261040051604052610420516060526101ff6103e0610fde565b6103e05161026c5750505f6104405260206104406103915661026c56610237565b6103a0516101e0511015610237576103a0516101e0525b610200516007811161126c57610320516040526102556103c0610ffb565b6103c0518160051b61022001526001810161020052505b600101818118610142575b50505f546101c051036101e0511015610299575f610320526020610320610391565b6101a051630dca59c1610340526020610340600461035c845afa6102bf573d5f5f3e3d5ffd5b60203d1061126c576103409050516103205261032051602061129c5f395f516370a08231610360526101a051610380526020610360602461037c845afa610308573d5f5f3e3d5ffd5b60203d1061126c5761036090505180820182811061126c5790509050610340526102005160208160051b018060408261020060045afa50505061034c6103606110ba565b610360516103405180820281158383830414171561126c5790509050670de0b6b3a7640000810490506103205180820382811161126c57905090506103805260206103805bf35b633278d11f8118610e84573461126c5733610120526105fe56610e84565b639faa3c9181186103cd573461126c5760035460405260206040f35b63813111ab8118610e845760443610341761126c57602954331861126c57670de0b6b3a76400006004351161126c57670de0b6b3a76400006024351161126c576004356002556024356003557f069906c4131a2e2c0b2f32f351644b280d95237fa3f095f91ac69cac88ab92346040600460403760406040a100610e84565b63245a7bfc8118610468573461126c5760045460405260206040f35b633ad799aa81186104c95760243610341761126c57602954331861126c57662386f26fc100006004351161126c576004355f557fb4a3856a5d3f85a0db622badf557a5c47e98ef4ce2f9fced462328721ee80c7660043560405260206040a1005b634fc6286a8118610e845760243610341761126c57602954331861126c5768056bc75e2d631000006004351161126c576004356001557f406e5474c6819832e7834a919ce48a8c8d909e2d9a3a0fe5378844c3b51b46a260043560405260206040a100610e84565b63f6235138811861057d5760243610341761126c5760043560055481101561126c5760021b600601805460405260018101546060526002810154608052600381015460a0525060806040f35b639c868ac08118610e84573461126c5760285460405260206040f3610e84565b63cab4d3db8118610e84573461126c5760275460405260206040f3610e84565b63f851a44081186105d9573461126c5760295460405260206040f35b63990ca2b08118610e845760243610341761126c576004358060a01c61126c57610120525b60026028541615610618575f610140526020610140610782565b670de0b6b3a764000160045463a035b1fe610140526020610140600461015c845afa610646573d5f5f3e3d5ffd5b60203d1061126c5761014090505110610668575f610180526020610180610782565b6026610120516020525f5260405f205461014052610140511561077757610140516001810381811161126c57905060055481101561126c5760021b60060180546101605260018101546101805260028101546101a05260038101546101c0525061016051604052610180516060526101a0516080526101c05160a0526106ef6101e0610e88565b6101e0516102405261016051604052610180516060526101a0516080526101c05160a05261071e610200610f33565b6102005161026052610240516040526102605160605261073f610220610fde565b6102205115610777577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610280526020610280610782565b5f6101605260206101605bf3610e84565b63680c77838118610e84573461126c57602a5460405260206040f3610e84565b63e9cbd82281186107c6573461126c57602061129c60403960206040f35b637717b58c8118610e845760443610341761126c57600435600401600881351161126c5780355f816008811161126c57801561082357905b8060051b6020850101358060a01c61126c578160051b606001526001018181186107fe575b5050806040525050602954331861126c5760055460208160071b015f81601f0160051c6021811161126c57801561086f57905b80600501548160051b6101600152600101818118610856575b505050505f6040516008811161126c5780156109db57905b8060051b60600151610580526026610580516020525f5260405f20546001810381811161126c5790506105a052610160516001810381811161126c5790506105c0526105c0516105a051101561097d576105c0516101605181101561126c5760071b6101800180516105e052602081015161060052604081015161062052606081015161064052506105a0516101605181101561126c5760071b610180016105e0518152610600516020820152610620516040820152610640516060820152506105a051806001016001811061126c57905060266105a0516101605181101561126c5760071b61018001516020525f5260405f20555b600161016051801561126c57038061016052505f6026610580516020525f5260405f20557f52182c3057b74a074adcacf89ba9ff9860a1265c89cfecd998a111e06bc80267610580516105e05260206105e0a1600101818118610887575b50506101605160208160071b015f81601f0160051c6021811161126c578015610a1957905b8060051b61016001518160050155600101818118610a00575b5050505000610e84565b6324039e728118610a3d573461126c57336101a052610098565b63aa7c366c8118610e845760243610341761126c576004358060021c61126c57604052336029548118610a71576001610a78565b602a548118155b90501561126c576040516028557f4f68ba80bc10140c2ec9990a643fe65220bf8b240f8da93df41290bceee79cd26040516060523360805260406060a100610e84565b63b3a6ace48118610e845760443610341761126c57600435600401600881351161126c5780355f816008811161126c578015610b1857905b8060051b6020850101358060a01c61126c578160051b60600152600101818118610af3575b5050806040525050602954331861126c57600554610160525f6040516008811161126c578015610cf057905b8060051b60600151610180526026610180516020525f5260405f205461126c57610180516316f0115b6101c05260206101c060046101dc845afa610b8a573d5f5f3e3d5ffd5b60203d1061126c576101c0518060a01c61126c57610200526102009050516101a0526101a0515a63687276536101e45260045f610204526020016101e0526101e0505f5f6101e0516102005f8686f1905090506101c052610180516101e0526101a051610200526101805163f96b9f18610260526020610260600461027c845afa610c17573d5f5f3e3d5ffd5b60203d1061126c57610260518060011c61126c576102a0526102a0905051610220526101c051610240526005546007811161126c578060021b6006016101e0518155610200516001820155610220516002820155610240516003820155506001810160055550610160516001810181811061126c57905061016052610160516026610180516020525f5260405f20557f16258839d7d9de7d5af567f0f747bb55d4b7a8fb7d125b7c3d55f5e5f573a6806101e051610260526102005161028052610220516102a0526060610260a1600101818118610b44575b505000610e84565b634c2cf2cd8118610e845760243610341761126c576004358060a01c61126c57604052602954331861126c576040516004557fe3019176e17c666cf4037ff4eaf90f47c7eaa9d7445cac6c1577d7a6fb903b8f60405160605260206060a100610e84565b63e41ab7718118610e845760243610341761126c576004358060a01c61126c57604052602954331861126c576040516027557fffb40bfdfd246e95f543d08d9713c339f1d90fa9265e39b4f562f9011d7c919f60405160605260206060a100610e84565b63e9333fab8118610e845760243610341761126c576004358060a01c61126c57604052602954331861126c576040516029557f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a160405160605260206060a100610e84565b6380b6d8028118610e845760243610341761126c576004358060a01c61126c57604052602954331861126c57604051602a557fb72d36542c9b761c0d9b215bddd7b59c055dd4fb2f6c5da22e964720458ddff160405160605260206060a1005b5f5ffd5b5f60c05260a051610eca5760605163f2388acb60e052602060e0600460fc845afa610eb5573d5f5f3e3d5ffd5b60203d1061126c5760e090505160c052610f02565b60605163ec02386260e0525f61010052602060e0602460fc845afa610ef1573d5f5f3e3d5ffd5b60203d1061126c5760e090505160c0525b60805115610f2b5760c051801561126c57806ec097ce7bc90715b34b9f100000000004905060c0525b60c051815250565b5f60c05260a051610f75576060516386fc88d360e052602060e0600460fc845afa610f60573d5f5f3e3d5ffd5b60203d1061126c5760e090505160c052610fad565b606051636872765360e0525f61010052602060e0602460fc845afa610f9c573d5f5f3e3d5ffd5b60203d1061126c5760e090505160c0525b60805115610fd65760c051801561126c57806ec097ce7bc90715b34b9f100000000004905060c0525b60c051815250565b60015460805260805160011b606051604051608051010310815250565b604051630dca59c1608052602060806004609c845afa61101d573d5f5f3e3d5ffd5b60203d1061126c576080905051606052606051670de0b6b3a7640000810281670de0b6b3a764000082041861126c579050606051806001016001811061126c579050602061129c5f395f516370a0823160805260405160a052602060806024609c845afa61108d573d5f5f3e3d5ffd5b60203d1061126c57608090505180820182811061126c5790509050801561126c5780820490509050815250565b5f610160525f6040516008811161126c57801561120257905b8060051b60600151610180526101605161018051670de0b6b3a7640000810281670de0b6b3a764000082041861126c5790508060b571010000000000000000000000000000000000821061112e578160801c91508060401b90505b6901000000000000000000821061114c578160401c91508060201b90505b650100000000008210611166578160201c91508060101b90505b6301000000821061117e578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808304808281188284100218905090509050905080820182811061126c5790509050610160526001018181186110d3575b50506002546003546101605180820281158383830414171561126c5790509050670de0b6b3a76400008104905080820182811061126c57905090506fffffffffffffffffffffffffffffffff811161126c576002810a9050670de0b6b3a764000081049050815250565b5f80fd07a80d5c0e240e840e84078805bd0e8400180e840e8400370e840cf80a230dc0044c059d053100570abb03b18419129c81182c1820a16576797065728300030a0016000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e00000000000000000000000018672b1b0c623a30089a280ed9256379fb0e4e62000000000000000000000000ecb456ea5365865ebab8a2661b0c503410e9b34700000000000000000000000040907540d8a6c65c637785e8f8b742ae6b0b996800000000000000000000000000669df67e4827fcc0e48a1838a8d5ab79281909","name":"PegKeeperRegulator","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":false,"language":"vyper","evm_version":null,"can_be_visualized_via_sol2uml":false,"is_verified_via_sourcify":false,"additional_sources":[],"certified":false,"conflicting_implementations":null,"abi":[{"anonymous":false,"inputs":[{"indexed":false,"name":"peg_keeper","type":"address"},{"indexed":false,"name":"pool","type":"address"},{"indexed":false,"name":"is_inverse","type":"bool"}],"name":"AddPegKeeper","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"peg_keeper","type":"address"}],"name":"RemovePegKeeper","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"threshold","type":"uint256"}],"name":"WorstPriceThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"price_deviation","type":"uint256"}],"name":"PriceDeviation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"alpha","type":"uint256"},{"indexed":false,"name":"beta","type":"uint256"}],"name":"DebtParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"aggregator","type":"address"}],"name":"SetAggregator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fee_receiver","type":"address"}],"name":"SetFeeReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"is_killed","type":"uint256"},{"indexed":false,"name":"by","type":"address"}],"name":"SetKilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"admin","type":"address"}],"name":"SetAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"admin","type":"address"}],"name":"SetEmergencyAdmin","type":"event"},{"inputs":[{"name":"_stablecoin","type":"address"},{"name":"_agg","type":"address"},{"name":"_fee_receiver","type":"address"},{"name":"_admin","type":"address"},{"name":"_emergency_admin","type":"address"}],"outputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"stablecoin","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"provide_allowed","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_pk","type":"address"}],"name":"provide_allowed","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw_allowed","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_pk","type":"address"}],"name":"withdraw_allowed","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_peg_keepers","type":"address[]"}],"name":"add_peg_keepers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_peg_keepers","type":"address[]"}],"name":"remove_peg_keepers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_threshold","type":"uint256"}],"name":"set_worst_price_threshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_deviation","type":"uint256"}],"name":"set_price_deviation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_alpha","type":"uint256"},{"name":"_beta","type":"uint256"}],"name":"set_debt_parameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_agg","type":"address"}],"name":"set_aggregator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_fee_receiver","type":"address"}],"name":"set_fee_receiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_is_killed","type":"uint256"}],"name":"set_killed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_admin","type":"address"}],"name":"set_admin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_admin","type":"address"}],"name":"set_emergency_admin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"worst_price_threshold","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price_deviation","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"alpha","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beta","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aggregator","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"arg0","type":"uint256"}],"name":"peg_keepers","outputs":[{"components":[{"name":"peg_keeper","type":"address"},{"name":"pool","type":"address"},{"name":"is_inverse","type":"bool"},{"name":"include_index","type":"bool"}],"name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee_receiver","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"is_killed","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergency_admin","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0x000000000000000000000000f939e0a03fb07f59a73314e73794be0e57ac1b4e00000000000000000000000018672b1b0c623a30089a280ed9256379fb0e4e62000000000000000000000000ecb456ea5365865ebab8a2661b0c503410e9b34700000000000000000000000040907540d8a6c65c637785e8f8b742ae6b0b996800000000000000000000000000669df67e4827fcc0e48a1838a8d5ab79281909"}