ETH Price: $2,011.97 (-2.90%)

Contract

0xFa966239028b183F66C4B34B15c08b451EBa8fc3

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Adjust_loan1216081792024-06-19 16:38:55280 days ago1718815135IN
0xFa966239...51EBa8fc3
0 ETH0.0000269551260.06075683
Close_loan1216058262024-06-19 15:20:29280 days ago1718810429IN
0xFa966239...51EBa8fc3
0 ETH0.0000434639910.06053545
Create_loan1216050542024-06-19 14:54:45280 days ago1718808885IN
0xFa966239...51EBa8fc3
0 ETH0.0000350023050.06086645
Adjust_loan1216005502024-06-19 12:24:37280 days ago1718799877IN
0xFa966239...51EBa8fc3
0 ETH0.0000263481680.06022669
Adjust_loan1215986972024-06-19 11:22:51280 days ago1718796171IN
0xFa966239...51EBa8fc3
0 ETH0.0000607953870.06152609
Close_loan1215825032024-06-19 2:23:03280 days ago1718763783IN
0xFa966239...51EBa8fc3
0 ETH0.0000177084410.0608689
Adjust_loan1215819822024-06-19 2:05:41280 days ago1718762741IN
0xFa966239...51EBa8fc3
0 ETH0.0000306975030.06163105
Adjust_loan1215819702024-06-19 2:05:17280 days ago1718762717IN
0xFa966239...51EBa8fc3
0 ETH0.000044892860.06143703
Adjust_loan1215819622024-06-19 2:05:01280 days ago1718762701IN
0xFa966239...51EBa8fc3
0 ETH0.0000453313640.06127126
Create_loan1215819442024-06-19 2:04:25280 days ago1718762665IN
0xFa966239...51EBa8fc3
0 ETH0.0000507304690.06214444
Adjust_loan1215377662024-06-18 1:31:49281 days ago1718674309IN
0xFa966239...51EBa8fc3
0 ETH0.0000615931220.12063133
Adjust_loan1215377462024-06-18 1:31:09281 days ago1718674269IN
0xFa966239...51EBa8fc3
0 ETH0.0000590495950.12262189
Create_loan1215291022024-06-17 20:43:01282 days ago1718656981IN
0xFa966239...51EBa8fc3
0 ETH0.0000427010120.06107049
Create_loan1215231122024-06-17 17:23:21282 days ago1718645001IN
0xFa966239...51EBa8fc3
0 ETH0.0000341037920.06054145
Close_loan1214873232024-06-16 21:30:23283 days ago1718573423IN
0xFa966239...51EBa8fc3
0 ETH0.0000002714630.00097853
Create_loan1214872322024-06-16 21:27:21283 days ago1718573241IN
0xFa966239...51EBa8fc3
0 ETH0.0000009359590.00101678
Close_loan1214871162024-06-16 21:23:29283 days ago1718573009IN
0xFa966239...51EBa8fc3
0 ETH0.0000002723930.00099023
Adjust_loan1214871082024-06-16 21:23:13283 days ago1718572993IN
0xFa966239...51EBa8fc3
0 ETH0.0000008061370.00090053
Create_loan1214870242024-06-16 21:20:25283 days ago1718572825IN
0xFa966239...51EBa8fc3
0 ETH0.000000890940.00097412
Close_loan1214170192024-06-15 6:26:55284 days ago1718432815IN
0xFa966239...51EBa8fc3
0 ETH0.0000002814140.00100101
Create_loan1214164942024-06-15 6:09:25284 days ago1718431765IN
0xFa966239...51EBa8fc3
0 ETH0.0000013812190.00150674
Close_loan1214137372024-06-15 4:37:31284 days ago1718426251IN
0xFa966239...51EBa8fc3
0 ETH0.0000004323430.00156024
Adjust_loan1214137262024-06-15 4:37:09284 days ago1718426229IN
0xFa966239...51EBa8fc3
0 ETH0.0000005948420.00101455
Adjust_loan1214137192024-06-15 4:36:55284 days ago1718426215IN
0xFa966239...51EBa8fc3
0 ETH0.0000014484630.00161913
Adjust_loan1214137072024-06-15 4:36:31284 days ago1718426191IN
0xFa966239...51EBa8fc3
0 ETH0.0000007247250.00127508
View all transactions

Latest 4 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
1210152112024-06-05 23:13:19294 days ago1717629199
0xFa966239...51EBa8fc3
 Contract Creation0 ETH
1210152112024-06-05 23:13:19294 days ago1717629199
0xFa966239...51EBa8fc3
 Contract Creation0 ETH
1210150432024-06-05 23:07:43294 days ago1717628863
0xFa966239...51EBa8fc3
 Contract Creation0 ETH
1210150432024-06-05 23:07:43294 days ago1717628863
0xFa966239...51EBa8fc3
 Contract Creation0 ETH

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CDP Main Controller

Compiler Version
vyper:0.3.10

Optimization Enabled:
N/A

Other Settings:
default evmVersion, None license

Contract Source Code (Vyper language format)

# @version 0.3.10
"""
@title CDP Main Controller
@author Curve.Fi (with edits by defidotmoney)
@license Copyright (c) Curve.Fi, 2020-2023 - all rights reserved
"""

interface ERC20:
    def mint(_to: address, _value: uint256) -> bool: nonpayable
    def burn(_to: address, _value: uint256) -> bool: nonpayable
    def transferFrom(_from: address, _to: address, _value: uint256) -> bool: nonpayable
    def transfer(_to: address, _value: uint256) -> bool: nonpayable
    def balanceOf(account: address) -> uint256: view

interface PriceOracle:
    def price() -> uint256: view
    def price_w() -> uint256: nonpayable

interface AMM:
    def initialize(
        operator: address,
        oracle: PriceOracle,
        collateral: address,
        _base_price: uint256,
        fee: uint256,
        admin_fee: uint256
    ): nonpayable
    def set_rate(rate: uint256) -> uint256: nonpayable
    def price_oracle() -> uint256: view
    def rate() -> uint256: view
    def get_sum_xy(account: address) -> (uint256, uint256): view
    def read_user_tick_numbers(receiver: address) -> int256[2]: view
    def p_oracle_up(n: int256) -> uint256: view
    def p_oracle_down(n: int256) -> uint256: view
    def A() -> uint256: view

interface MarketOperator:
    def initialize(
        amm: address,
        collateral_token: address,
        debt_ceiling: uint256,
        loan_discount: uint256,
        liquidation_discount: uint256,
    ): nonpayable
    def total_debt() -> uint256: view
    def pending_debt() -> uint256: view
    def debt_ceiling() -> uint256: view
    def debt(account: address) -> uint256: view
    def max_borrowable(collateral: uint256, n_bands: uint256) -> uint256: view
    def health(account: address, full: bool) -> int256: view
    def collect_fees() -> (uint256, uint256[2]): nonpayable
    def create_loan(account: address, coll_amount: uint256, debt_amount: uint256, n_bands: uint256) -> uint256: nonpayable
    def adjust_loan(account: address, coll_amount: int256, debt_amount: int256, max_active_band: int256) -> int256: nonpayable
    def close_loan(account: address) -> (int256, uint256, uint256[2]): nonpayable
    def liquidate(caller: address, target: address, min_x: uint256, frac: uint256) -> (int256, uint256, uint256[2]): nonpayable
    def AMM() -> address: view
    def A() -> uint256: view
    def pending_account_state_calculator(
        account: address,
        coll_change: int256,
        debt_change: int256,
        num_bands: uint256
    ) -> (uint256, uint256, uint256, int256, int256[2]): view

interface MonetaryPolicy:
    def rate(market: MarketOperator) -> uint256: view
    def rate_write(market: address) -> uint256: nonpayable

interface PegKeeper:
    def set_regulator(regulator: address): nonpayable

interface PegKeeperRegulator:
    def active_debt() -> uint256: view
    def get_peg_keepers_with_debt_ceilings() -> (DynArray[PegKeeper, 256], DynArray[uint256, 256]): view
    def init_migrate_peg_keepers(peg_keepers: DynArray[PegKeeper, 256], debt_ceilings: DynArray[uint256, 256]): nonpayable

interface CoreOwner:
    def owner() -> address: view
    def feeReceiver() -> address: view
    def guardian() -> address: view

interface MarketHook:
    def get_configuration() -> (uint256, bool[NUM_HOOK_IDS]): view



event AddMarket:
    collateral: indexed(address)
    market: address
    amm: address
    mp_idx: uint256

event SetDelegateApproval:
    account: indexed(address)
    delegate: indexed(address)
    is_approved: bool

event SetDelegationEnabled:
    caller: address
    is_enabled: bool

event SetProtocolEnabled:
    caller: address
    is_enabled: bool

event SetImplementations:
    A: indexed(uint256)
    amm: address
    market: address

event AddMarketHook:
    market: indexed(address)
    hook: indexed(address)
    hook_type: uint256
    active_hooks: bool[NUM_HOOK_IDS]

event RemoveMarketHook:
    market: indexed(address)
    hook: indexed(address)
    hook_debt_released: uint256

event HookDebtAjustment:
    market: indexed(address)
    hook: indexed(address)
    adjustment: int256
    new_hook_debt: uint256
    new_total_hook_debt: uint256

event AddMonetaryPolicy:
    mp_idx: indexed(uint256)
    monetary_policy: MonetaryPolicy

event ChangeMonetaryPolicy:
    mp_idx: indexed(uint256)
    monetary_policy: MonetaryPolicy

event ChangeMonetaryPolicyForMarket:
    market: indexed(address)
    mp_idx: indexed(uint256)

event SetGlobalMarketDebtCeiling:
    debt_ceiling: uint256

event SetPegKeeperRegulator:
    regulator: address
    with_migration: bool

event CreateLoan:
    market: indexed(address)
    account: indexed(address)
    caller: indexed(address)
    coll_amount: uint256
    debt_amount: uint256

event AdjustLoan:
    market: indexed(address)
    account: indexed(address)
    caller: indexed(address)
    coll_adjustment: int256
    debt_adjustment: int256

event CloseLoan:
    market: indexed(address)
    account: indexed(address)
    caller: indexed(address)
    coll_withdrawn: uint256
    debt_withdrawn: uint256
    debt_repaid: uint256

event LiquidateLoan:
    market: indexed(address)
    liquidator: indexed(address)
    account: indexed(address)
    coll_received: uint256
    debt_received: uint256
    debt_repaid: uint256

event CollectAmmFees:
    market: indexed(address)
    amm_coll_fees: uint256
    amm_debt_fees: uint256

event CollectFees:
    minted: uint256
    redeemed: uint256
    total_debt: uint256
    fee: uint256


struct MarketContracts:
    collateral: address
    amm: address
    mp_idx: uint256

struct Implementations:
    amm: address
    market_operator: address

struct MarketHookData:
    hooks: address
    hook_type: uint256
    active_hooks: bool[NUM_HOOK_IDS]


enum HookId:
    ON_CREATE_LOAN
    ON_ADJUST_LOAN
    ON_CLOSE_LOAN
    ON_LIQUIDATION

enum HookType:
    VALIDATION_ONLY
    FEE_ONLY
    FEE_AND_REBATE


NUM_HOOK_IDS: constant(uint256) = 4
MAX_HOOKS: constant(uint256) = 4

# Limits
MIN_A: constant(uint256) = 2
MAX_A: constant(uint256) = 10000
MAX_RATE: constant(uint256) = 43959106799  # 300% APY
MIN_FEE: constant(uint256) = 10**6  # 1e-12, still needs to be above 0
MAX_FEE: constant(uint256) = 10**17  # 10%
MAX_ADMIN_FEE: constant(uint256) = 10**18  # 100%
MAX_LOAN_DISCOUNT: constant(uint256) = 5 * 10**17
MIN_LIQUIDATION_DISCOUNT: constant(uint256) = 10**16

STABLECOIN: public(immutable(ERC20))
CORE_OWNER: public(immutable(CoreOwner))
peg_keeper_regulator: public(PegKeeperRegulator)

markets: public(DynArray[MarketOperator, 65536])
collaterals: public(DynArray[address, 65536])
collateral_markets: HashMap[address, DynArray[address, 256]]
market_contracts: public(HashMap[address, MarketContracts])
monetary_policies: public(MonetaryPolicy[256])
n_monetary_policies: public(uint256)

global_market_debt_ceiling: public(uint256)
total_debt: public(uint256)
minted: public(uint256)
redeemed: public(uint256)

isApprovedDelegate: public(HashMap[address, HashMap[address, bool]])
isDelegationEnabled: public(bool)
is_protocol_enabled: public(bool)

implementations: HashMap[uint256, Implementations]

market_hooks: HashMap[address, DynArray[uint256, MAX_HOOKS]]
hook_debt: HashMap[address, HashMap[address, uint256]]
total_hook_debt: public(uint256)


@external
def __init__(
    core: CoreOwner,
    stable: ERC20,
    monetary_policies: DynArray[MonetaryPolicy, 10],
    debt_ceiling: uint256
):
    CORE_OWNER = core
    STABLECOIN = stable

    idx: uint256 = 0
    for mp in monetary_policies:
        log AddMonetaryPolicy(idx, mp)
        self.monetary_policies[idx] = mp
        idx += 1
    self.n_monetary_policies = idx

    self.global_market_debt_ceiling = debt_ceiling
    log SetGlobalMarketDebtCeiling(debt_ceiling)

    self.is_protocol_enabled = True
    self.isDelegationEnabled = True


# --- external view functions ---

@view
@external
def owner() -> address:
    return CORE_OWNER.owner()


@view
@external
def get_market_count() -> uint256:
    return len(self.markets)


@view
@external
def get_collateral_count() -> uint256:
    return len(self.collaterals)


@view
@external
def get_all_markets() -> DynArray[MarketOperator, 65536]:
    return self.markets


@view
@external
def get_all_collaterals() -> DynArray[address, 65536]:
    return self.collaterals


@view
@external
def get_all_markets_for_collateral(collateral: address) -> DynArray[address, 256]:
    return self.collateral_markets[collateral]


@view
@external
def get_market(collateral: address, i: uint256 = 0) -> address:
    """
    @notice Get market address for collateral
    @dev Returns empty(address) if market does not exist
    @param collateral Address of collateral token
    @param i Access the i-th market within the list
    """
    if i >= len(self.collateral_markets[collateral]):
        return empty(address)
    return self.collateral_markets[collateral][i]


@view
@external
def get_amm(collateral: address, i: uint256 = 0) -> address:
    """
    @notice Get AMM address for collateral
    @dev Returns empty(address) if market does not exist
    @param collateral Address of collateral token
    @param i Access the i-th collateral within the list
    """
    if i >= len(self.collateral_markets[collateral]):
        return empty(address)
    market: address = self.collateral_markets[collateral][i]
    return self.market_contracts[market].amm


@view
@external
def max_borrowable(market: MarketOperator, coll_amount: uint256, n_bands: uint256) -> uint256:
    """
    @notice Calculation of maximum which can be borrowed in the given market
    @param market Market where the loan will be taken
    @param coll_amount Collateral amount against which to borrow
    @param n_bands number of bands the collateral will be deposited over
    @return Maximum amount of stablecoin that can be borrowed
    """
    debt_ceiling: uint256 = self.global_market_debt_ceiling
    total_debt: uint256 = self.total_debt + market.pending_debt()
    if total_debt >= debt_ceiling:
        return 0

    global_max: uint256 = debt_ceiling - total_debt
    market_max: uint256 = market.max_borrowable(coll_amount, n_bands)

    return min(global_max, market_max)


@view
@external
def get_implementations(A: uint256) -> Implementations:
    return self.implementations[A]


@view
@external
def get_market_hooks(market: address) -> DynArray[MarketHookData, MAX_HOOKS]:
    """
    @notice Get the hook contracts and active hooks for the given market
    @param market Market address. Set as empty(address) for global hooks.
    @return market hooks
    """
    hookdata_packed_array: DynArray[uint256, MAX_HOOKS] = self.market_hooks[market]
    hookdata_array: DynArray[MarketHookData, MAX_HOOKS] = []


    for hookdata_packed in hookdata_packed_array:
        hookdata: MarketHookData = empty(MarketHookData)
        hookdata.hooks = self._get_hook_address(hookdata_packed)
        hookdata.hook_type = (hookdata_packed & 7) >> 1

        for i in range(NUM_HOOK_IDS):
            if hookdata_packed >> i & 8 != 0:
                hookdata.active_hooks[i] = True

        hookdata_array.append(hookdata)

    return hookdata_array


@view
@external
def get_market_hook_debt(market: address, hook: address) -> uint256:
    """
    @notice Get the total aggregate hook debt adjustments for the given market
    @dev The sum of all hook debt adjustments cannot ever be less than zero
         or the system will have uncollateralized debt.
    """
    return self.hook_debt[market][hook]


@view
@external
def get_monetary_policy_for_market(market: address) -> MonetaryPolicy:
    """
    @notice Get the address of the monetary policy for `market`
    """
    c: MarketContracts = self.market_contracts[market]

    if c.collateral == empty(address):
        return empty(MonetaryPolicy)

    return self.monetary_policies[c.mp_idx]


@view
@external
def get_peg_keeper_active_debt() -> uint256:
    """
    @notice Get the total active debt across all peg keepers
    """
    regulator: PegKeeperRegulator = self.peg_keeper_regulator
    if regulator.address == empty(address):
        return 0
    return regulator.active_debt()


@view
@external
def stored_admin_fees() -> uint256:
    """
    @notice Calculate the amount of fees obtained from the interest
    """
    return self.total_debt + self.redeemed - self.minted - self.total_hook_debt


@view
@external
def on_create_loan_hook_adjustment(
    account: address,
    market: address,
    coll_amount: uint256,
    debt_amount: uint256,
) -> int256:
    """
    @notice Get the aggregate hook debt adjustment when creating a new loan
    @param account Account to open the loan for
    @param market Market where the loan will be opened
    @param coll_amount Collateral amount to deposit
    @param debt_amount Stablecoin amount to mint
    @return adjustment amount applied to the new debt created
    """
    return self._call_view_hooks(
        market,
        HookId.ON_CREATE_LOAN,
        _abi_encode(
            account,
            market,
            coll_amount,
            debt_amount,
            method_id=method_id("on_create_loan_view(address,address,uint256,uint256)")
        ),
        self._positive_only_bounds(debt_amount)
    )


@view
@external
def on_adjust_loan_hook_adjustment(
    account: address,
    market: address,
    coll_change: int256,
    debt_change: int256
) -> int256:
    """
    @notice Get the aggregate hook debt adjustment when adjusting an existing loan
    @param account Account to adjust the loan for
    @param market Market of the loan being adjusted
    @param coll_change Collateral adjustment amount. A positive value deposits, negative withdraws.
    @param debt_change Debt adjustment amount. A positive value mints, negative burns.
    @return adjustment amount applied to `debt_change`
    """
    return self._call_view_hooks(
        market,
        HookId.ON_ADJUST_LOAN,
        _abi_encode(
            account,
            market,
            coll_change,
            debt_change,
            method_id=method_id("on_adjust_loan_view(address,address,int256,int256)")
        ),
        self._adjust_loan_bounds(debt_change)
    )


@view
@external
def on_close_loan_hook_adjustment(account: address, market: address) -> int256:
    """
    @notice Get the aggregate hook debt adjustment when closing a loan
    @param account The account to close the loan for
    @param market Market of the loan being closed
    @return adjustment amount applied to the debt burned when closing the loan
    """
    debt: uint256 = MarketOperator(market).debt(account)
    return self._call_view_hooks(
        market,
        HookId.ON_CLOSE_LOAN,
        _abi_encode(account, market, debt, method_id=method_id("on_close_loan_view(address,address,uint256)")),
        self._positive_only_bounds(debt)
    )


@view
@external
def on_liquidate_hook_adjustment(caller: address, market: address, target: address) -> int256:
    """
    @notice Get the aggregate hook debt adjustment when liquidating a loan
    @param caller Caller address that will perform the liquidations
    @param market Market to check for liquidations
    @param target Address of the account to be liquidated
    @return adjustment amount applied to the debt burned during liquidation
    """
    debt: uint256 = MarketOperator(market).debt(target)
    return self._call_view_hooks(
        market,
        HookId.ON_LIQUIDATION,
        _abi_encode(
            caller,
            market,
            target,
            debt,
            method_id=method_id("on_liquidation_view(address,address,address,uint256)")
        ),
        self._positive_only_bounds(debt)
    )


# --- unguarded nonpayable functions ---

@external
def setDelegateApproval(delegate: address, is_approved: bool):
    """
    @dev Functions that supports delegation include an `account` input allowing
         the delegated caller to indicate who they are calling on behalf of.
         In executing the call, all internal state updates are applied for
         `account` and all value transfers occur to or from the caller.

        For example: a delegated call to `create_loan` will transfer collateral
        from the caller, create the debt position for `account`, and send newly
        minted stablecoins to the caller.
    """
    self.isApprovedDelegate[msg.sender][delegate] = is_approved
    log SetDelegateApproval(msg.sender, delegate, is_approved)


@external
@nonreentrant('lock')
def create_loan(
    account: address,
    market: address,
    coll_amount: uint256,
    debt_amount: uint256,
    n_bands: uint256
):
    """
    @notice Create loan
    @param account Account to open the loan for
    @param market Market where the loan will be opened
    @param coll_amount Collateral amount to deposit
    @param debt_amount Stablecoin amount to mint
    @param n_bands Number of bands to deposit collateral into
                   Can be from market.MIN_TICKS() to market.MAX_TICKS()
    """
    assert coll_amount > 0 and debt_amount > 0, "DFM:C 0 coll or debt"
    self._assert_is_protocol_enabled()
    self._assert_caller_or_approved_delegate(account)
    c: MarketContracts = self._get_market_contracts_or_revert(market)

    hook_adjust: int256 = self._call_hooks(
        market,
        HookId.ON_CREATE_LOAN,
        _abi_encode(
            account,
            market,
            coll_amount,
            debt_amount,
            method_id=method_id("on_create_loan(address,address,uint256,uint256)")
        ),
        self._positive_only_bounds(debt_amount)
    )
    debt_amount_final: uint256 = self._uint_plus_int(debt_amount, hook_adjust)

    self._deposit_collateral(msg.sender, c.collateral, c.amm, coll_amount)
    debt_increase: uint256 = MarketOperator(market).create_loan(account, coll_amount, debt_amount_final, n_bands)

    total_debt: uint256 = self.total_debt + debt_increase
    self._assert_below_debt_ceiling(total_debt)

    self.total_debt = total_debt
    self.minted += debt_amount

    STABLECOIN.mint(msg.sender, debt_amount)

    self._update_rate(market, c.amm, c.mp_idx)

    log CreateLoan(market, account, msg.sender, coll_amount, debt_amount_final)


@external
@nonreentrant('lock')
def adjust_loan(
    account: address,
    market: address,
    coll_change: int256,
    debt_change: int256,
    max_active_band: int256 = max_value(int256)
):
    """
    @notice Adjust collateral/debt amounts for an existing loan
    @param account Account to adjust the loan for
    @param market Market of the loan being adjusted
    @param coll_change Collateral adjustment amount. A positive value deposits, negative withdraws.
    @param debt_change Debt adjustment amount. A positive value mints, negative burns.
    @param max_active_band Maximum active band (used to prevent front-running)
    """
    assert coll_change != 0 or debt_change != 0, "DFM:C No change"

    self._assert_is_protocol_enabled()
    self._assert_caller_or_approved_delegate(account)
    c: MarketContracts = self._get_market_contracts_or_revert(market)

    debt_change_final: int256 = self._call_hooks(
        market,
        HookId.ON_ADJUST_LOAN,
        _abi_encode(
            account,
            market,
            coll_change,
            debt_change,
            method_id=method_id("on_adjust_loan(address,address,int256,int256)")
        ),
        self._adjust_loan_bounds(debt_change)
    ) + debt_change

    debt_adjustment: int256 = MarketOperator(market).adjust_loan(account, coll_change, debt_change_final, max_active_band)

    total_debt: uint256 = self._uint_plus_int(self.total_debt, debt_adjustment)
    self.total_debt = total_debt

    if debt_change != 0:
        debt_change_abs: uint256 = convert(abs(debt_change), uint256)
        if debt_change > 0:
            self._assert_below_debt_ceiling(total_debt)
            self.minted += debt_change_abs
            STABLECOIN.mint(msg.sender, debt_change_abs)
        else:
            self.redeemed += debt_change_abs
            STABLECOIN.burn(msg.sender, debt_change_abs)

    if coll_change != 0:
        coll_change_abs: uint256 = convert(abs(coll_change), uint256)
        if coll_change > 0:
            self._deposit_collateral(msg.sender, c.collateral, c.amm, coll_change_abs)
        else:
            self._withdraw_collateral(msg.sender, c.collateral, c.amm, coll_change_abs)

    self._update_rate(market, c.amm, c.mp_idx)

    log AdjustLoan(market, account, msg.sender, coll_change, debt_change_final)


@external
@nonreentrant('lock')
def close_loan(account: address, market: address):
    """
    @notice Close an existing loan
    @dev This function does not interact with the market's price oracle, so that
         users can still close their loans in case of a reverting oracle.
    @param account The account to close the loan for
    @param market Market of the loan being closed
    """
    self._assert_caller_or_approved_delegate(account)
    c: MarketContracts = self._get_market_contracts_or_revert(market)

    debt_adjustment: int256 = 0
    burn_amount: uint256 = 0
    xy: uint256[2] = empty(uint256[2])
    debt_adjustment, burn_amount, xy = MarketOperator(market).close_loan(account)

    burn_adjust: int256 = self._call_hooks(
        market,
        HookId.ON_CLOSE_LOAN,
        _abi_encode(account, market, burn_amount, method_id=method_id("on_close_loan(address,address,uint256)")),
        self._positive_only_bounds(burn_amount)
    )
    burn_amount = self._uint_plus_int(burn_amount, burn_adjust)

    self.redeemed += burn_amount
    self.total_debt = self._uint_plus_int(self.total_debt, debt_adjustment)

    if xy[0] > 0:
        STABLECOIN.transferFrom(c.amm, msg.sender, xy[0])
    STABLECOIN.burn(msg.sender, burn_amount)
    if xy[1] > 0:
        self._withdraw_collateral(msg.sender, c.collateral, c.amm, xy[1])

    self._update_rate(market, c.amm, c.mp_idx)

    log CloseLoan(market, account, msg.sender, xy[1], xy[0], burn_amount)


@external
@nonreentrant('lock')
def liquidate(market: address, target: address, min_x: uint256, frac: uint256 = 10**18):
    """
    @notice Perform a liquidation (or self-liquidation) on an unhealthy account
    @param market Market of the loan being liquidated
    @param target Address of the account to be liquidated
    @param min_x Minimal amount of stablecoin to receive (to avoid liquidators being sandwiched)
    @param frac Fraction to liquidate; 100% = 10**18
    """
    assert frac <= 10**18, "DFM:C frac too high"
    c: MarketContracts = self._get_market_contracts_or_revert(market)

    debt_adjustment: int256 = 0
    debt_amount: uint256 = 0
    xy: uint256[2] = empty(uint256[2])
    debt_adjustment, debt_amount, xy = MarketOperator(market).liquidate(msg.sender, target, min_x, frac)

    burn_adjust: int256 = self._call_hooks(
        market,
        HookId.ON_LIQUIDATION,
        _abi_encode(
            msg.sender,
            market,
            target,
            debt_amount,
            method_id=method_id("on_liquidation(address,address,address,uint256)")
        ),
        self._positive_only_bounds(debt_amount)
    )
    debt_amount = self._uint_plus_int(debt_amount, burn_adjust)

    self.redeemed += debt_amount
    self.total_debt = self._uint_plus_int(self.total_debt, debt_adjustment)

    burn_amm: uint256 = min(xy[0], debt_amount)
    if burn_amm != 0:
        STABLECOIN.burn(c.amm, burn_amm)

    if debt_amount > xy[0]:
        remaining: uint256 = unsafe_sub(debt_amount, xy[0])
        STABLECOIN.burn(msg.sender, remaining)
    elif xy[0] > debt_amount:
        STABLECOIN.transferFrom(c.amm, msg.sender, unsafe_sub(xy[0], debt_amount))

    if xy[1] > 0:
        self._withdraw_collateral(msg.sender, c.collateral, c.amm, xy[1])

    self._update_rate(market, c.amm, c.mp_idx)

    log LiquidateLoan(market, msg.sender, target, xy[1], xy[0], debt_amount)


@external
@nonreentrant('lock')
def collect_fees(market_list: DynArray[address, 255]) -> uint256:
    """
    @notice Collect admin fees across markets
    @param market_list List of markets to collect fees from. Can be left empty
                       to only claim already-stored interest fees.
    """
    self._assert_is_protocol_enabled()

    receiver: address = CORE_OWNER.feeReceiver()

    debt_increase_total: uint256 = 0
    i: uint256 = 0
    amm_list: address[255] = empty(address[255])
    mp_idx_list: uint256[255] = empty(uint256[255])

    # collect market fees and calculate aggregate debt increase
    for market in market_list:
        c: MarketContracts = self._get_market_contracts_or_revert(market)

        debt_increase: uint256 = 0
        xy: uint256[2] = empty(uint256[2])

        debt_increase, xy = MarketOperator(market).collect_fees()
        debt_increase_total += debt_increase

        if xy[0] > 0:
            STABLECOIN.transferFrom(c.amm, receiver, xy[0])
        if xy[1] > 0:
            self._withdraw_collateral(receiver, c.collateral, c.amm, xy[1])

        log CollectAmmFees(market, xy[1], xy[0])

        amm_list[i] = c.amm
        mp_idx_list[i] = c.mp_idx
        i = unsafe_add(i, 1)

    # update total debt and market rates
    total_debt: uint256 = self.total_debt + debt_increase_total
    self.total_debt = total_debt

    mint_total: uint256 = 0
    minted: uint256 = self.minted
    redeemed: uint256 = self.redeemed
    to_be_redeemed: uint256 = total_debt + redeemed - self.total_hook_debt

    if to_be_redeemed > minted:
        self.minted = to_be_redeemed
        mint_total = unsafe_sub(to_be_redeemed, minted)  # Now this is the fees to charge
        STABLECOIN.mint(receiver, mint_total)

    i = 0
    for market in market_list:
        self._update_rate(market, amm_list[i], mp_idx_list[i])
        i = unsafe_add(i, 1)

    log CollectFees(minted, redeemed, total_debt, mint_total)
    return mint_total


@external
def increase_hook_debt(market: address, hook: address, amount: uint256):
    """
    @notice Burn debt to increase the available hook debt value for a given
            market hook. This can be used to pre-fund hook debt rebates.
    """
    if market != empty(address):
        self._assert_market_exists(market)

    num_hooks: uint256 = len(self.market_hooks[market])
    for i in range(MAX_HOOKS + 1):
        if i == num_hooks:
            raise "DFM:C Unknown hook"
        hookdata: uint256 = self.market_hooks[market][i]
        if self._get_hook_address(hookdata) == hook:
            assert self._get_hook_type(hookdata) == HookType.FEE_AND_REBATE, "DFM:C Hook does not track debt"
            break

    STABLECOIN.burn(msg.sender, amount)
    self.hook_debt[market][hook] += amount
    self.total_hook_debt += amount
    self.redeemed += amount


# --- owner-only nonpayable functions ---

@external
def add_market(token: address, A: uint256, fee: uint256, admin_fee: uint256, oracle: PriceOracle,
               mp_idx: uint256, loan_discount: uint256, liquidation_discount: uint256,
               debt_ceiling: uint256) -> address[2]:
    """
    @notice Add a new market, creating an AMM and a MarketOperator from a blueprint
    @param token Collateral token address
    @param A Amplification coefficient; one band size is 1/A
    @param fee AMM fee in the market's AMM
    @param admin_fee AMM admin fee
    @param oracle Address of price oracle contract for this market
    @param mp_idx Monetary policy index for this market
    @param loan_discount Loan discount: allowed to borrow only up to x_down * (1 - loan_discount)
    @param liquidation_discount Discount which defines a bad liquidation threshold
    @param debt_ceiling Debt ceiling for this market
    @return (MarketOperator, AMM)
    """
    self._assert_only_owner()
    assert fee <= MAX_FEE, "DFM:C Fee too high"
    assert fee >= MIN_FEE, "DFM:C Fee too low"
    assert admin_fee <= MAX_ADMIN_FEE, "DFM:C Admin fee too high"
    assert liquidation_discount >= MIN_LIQUIDATION_DISCOUNT, "DFM:C liq discount too low"
    assert loan_discount <= MAX_LOAN_DISCOUNT, "DFM:C Loan discount too high"
    assert loan_discount > liquidation_discount, "DFM:C loan discount<liq discount"
    assert mp_idx < self.n_monetary_policies, "DFM:C invalid mp_idx"

    p: uint256 = oracle.price()
    assert p > 0, "DFM:C p == 0"
    assert oracle.price_w() == p, "DFM:C p != price_w"

    impl: Implementations = self.implementations[A]
    assert impl.amm != empty(address), "DFM:C No implementation for A"
    market: address = create_minimal_proxy_to(impl.market_operator)
    amm: address = create_minimal_proxy_to(impl.amm)

    MarketOperator(market).initialize(amm, token, debt_ceiling, loan_discount, liquidation_discount)
    AMM(amm).initialize(market, oracle, token, p, fee, admin_fee)

    self.markets.append(MarketOperator(market))
    if len(self.collateral_markets[token]) == 0:
        self.collaterals.append(token)
    self.collateral_markets[token].append(market)
    self.market_contracts[market] = MarketContracts({collateral: token, amm: amm, mp_idx: mp_idx})

    log AddMarket(token, market, amm, mp_idx)
    return [market, amm]


@external
def set_global_market_debt_ceiling(debt_ceiling: uint256):
    """
    @notice Set the global debt ceiling
    @dev There is no requirement for the global ceiling to be equal to the sum
         of the market ceilings. Individual markets may mint up to their own debt
         ceiling, so long as the aggregate debt does not exceed the global ceiling.
    """
    self._assert_only_owner()
    self.global_market_debt_ceiling = debt_ceiling

    log SetGlobalMarketDebtCeiling(debt_ceiling)


@external
def set_implementations(A: uint256, market: address, amm: address):
    """
    @notice Set new implementations for market and amm for given A
    @dev Already-deployed markets are unaffected by this change
    @param A Amplification co-efficient
    @param market Address of the market blueprint
    @param amm Address of the AMM blueprint
    """
    self._assert_only_owner()
    assert A >= MIN_A and A <= MAX_A, "DFM:C A outside bounds"

    if amm == market:
        assert amm == empty(address), "DFM:C matching implementations"
    else:
        assert amm != empty(address) and market != empty(address), "DFM:C empty implementation"
        assert MarketOperator(market).A() == A, "DFM:C incorrect market A"
        assert AMM(amm).A() == A, "DFM:C incorrect amm A"

    self.implementations[A] = Implementations({amm: amm, market_operator: market})
    log SetImplementations(A, amm, market)


@external
def add_market_hook(market: address, hook: address):
    """
    @notice Add a new callback hook contract for `market`
    @dev Hook contracts must adhere to the interface and specification defined
         at `interfaces/IControllerHooks.sol`
    @param market Market to add a hook for. Use empty(address) to set a global hook.
    @param hook Address of the hook contract.
    """
    self._assert_only_owner()

    if market != empty(address):
        self._assert_market_exists(market)

    market_hooks: DynArray[uint256, MAX_HOOKS] = self.market_hooks[market]
    assert len(market_hooks) < MAX_HOOKS, "DFM:C Maximum hook count reached"
    for hookdata in market_hooks:
        assert self._get_hook_address(hookdata) != hook, "DFM:C Hook already added"

    config: (uint256, bool[NUM_HOOK_IDS]) = MarketHook(hook).get_configuration()

    # add hook type to 3 lowest bits
    assert config[0] < 3, "DFM:C Invalid hook type"
    hookdata_packed: uint256 = 1 << config[0]

    # add hook ids starting from 4th bit
    for i in range(NUM_HOOK_IDS):
        if config[1][i]:
            hookdata_packed += 1 << (i + 3)

    assert (hookdata_packed >> 3) > 0, "DFM:C No active hook points"

    # add address starting from 96th bit
    hookdata_packed += convert(hook, uint256) << 96

    self.market_hooks[market].append(hookdata_packed)

    log AddMarketHook(market, hook, config[0], config[1])


@external
def remove_market_hook(market: address, hook: address):
    """
    @notice Remove a callback hook contract for `market`
    @dev If the hook type is `FEE_AND_REBATE` and the current `hook_debt`
         is non-zero, is balance is creditted to the protocol fees.
    @param market Market to remove the hooks from. Set as empty(address) to
                  remove a global hook.
    @param hook Address of the hook contract.
    """
    self._assert_only_owner()

    if market != empty(address):
        self._assert_market_exists(market)

    num_hooks: uint256 = len(self.market_hooks[market])
    for i in range(MAX_HOOKS + 1):
        if i == num_hooks:
            raise "DFM:C Unknown hook"
        if self._get_hook_address(self.market_hooks[market][i]) != hook:
            continue

        last_hookdata: uint256 = self.market_hooks[market].pop()
        if i < num_hooks - 1:
            self.market_hooks[market][i] = last_hookdata
        break

    hook_debt: uint256 = self.hook_debt[market][hook]
    if hook_debt > 0:
        self._adjust_hook_debt(market, hook, -convert(hook_debt, int256))

    log RemoveMarketHook(market, hook, hook_debt)



@external
def add_new_monetary_policy(monetary_policy: MonetaryPolicy):
    """
    @notice Add a new monetary policy
    @dev The new policy is assigned an identifier `mp_idx` which is used to
         associate it to individual markets
    """
    self._assert_only_owner()
    idx: uint256 = self.n_monetary_policies
    self.monetary_policies[idx] = monetary_policy
    self.n_monetary_policies = idx +1

    log AddMonetaryPolicy(idx, monetary_policy)


@external
def change_existing_monetary_policy(monetary_policy: MonetaryPolicy, mp_idx: uint256):
    """
    @notice Change the monetary policy at an existing `mp_idx`
    @dev Rates for markets using `mp_idx` are NOT updated,
         it is recommended to force an update via `collect_fees`
    """
    self._assert_only_owner()
    assert mp_idx < self.n_monetary_policies, "DFM:C invalid mp_idx"
    self.monetary_policies[mp_idx] = monetary_policy

    log ChangeMonetaryPolicy(mp_idx, monetary_policy)


@external
def change_market_monetary_policy(market: address, mp_idx: uint256):
    """
    @notice Modify the assigned `mp_idx` for the given market
    @dev Also updates the current market rate
    """
    self._assert_only_owner()
    self._assert_market_exists(market)
    assert mp_idx < self.n_monetary_policies, "DFM:C invalid mp_idx"

    self.market_contracts[market].mp_idx = mp_idx
    self._update_rate(market, self.market_contracts[market].amm, mp_idx)

    log ChangeMonetaryPolicyForMarket(market, mp_idx)


@external
def set_peg_keeper_regulator(regulator: PegKeeperRegulator, with_migration: bool):
    """
    @notice Set the active peg keeper regulator
    @dev The regulator must also be given permission to mint `STABLECOIN`
    @param regulator Address of the new peg keeper regulator. Can also be set to
                     empty(address) to have no active regulator.
    @param with_migration if True, all peg keepers from the old regulator are
                          added to the new regulator with the same debt ceilings.
    """
    self._assert_only_owner()
    old: PegKeeperRegulator = self.peg_keeper_regulator
    assert old != regulator, "DFM:C regulator unchanged"

    if with_migration:
        peg_keepers: DynArray[PegKeeper, 256] = []
        debt_ceilings: DynArray[uint256, 256] = []
        (peg_keepers, debt_ceilings) = old.get_peg_keepers_with_debt_ceilings()
        for pk in peg_keepers:
            pk.set_regulator(regulator.address)
        regulator.init_migrate_peg_keepers(peg_keepers, debt_ceilings)

    self.peg_keeper_regulator = regulator

    log SetPegKeeperRegulator(regulator.address, with_migration)


@external
def set_protocol_enabled(is_enabled: bool):
    """
    @notice Enable or disable the protocol in case of an emergency.
    @dev * While disabled, `close_loan` and `liquidate` are the only callable
           functions related to loan management.
         * Only the owner can enable.
         * The owner and the guardian are both able to disable.
    """
    self._assert_owner_or_guardian_toggle(is_enabled)
    self.is_protocol_enabled = is_enabled

    log SetProtocolEnabled(msg.sender, is_enabled)


@external
def setDelegationEnabled(is_enabled: bool):
    """
    @notice Enable or disable all delegated operations within this contract
    @dev Delegated operations are enabled by default upon deployment.
         Only the owner can enable. The owner or the guardian can disable.
    """
    self._assert_owner_or_guardian_toggle(is_enabled)
    self.isDelegationEnabled = is_enabled

    log SetDelegationEnabled(msg.sender, is_enabled)



# --- internal functions ---

@view
@internal
def _assert_only_owner():
    assert msg.sender == CORE_OWNER.owner(), "DFM:C Only owner"


@view
@internal
def _assert_owner_or_guardian_toggle(is_enabled: bool):
    if msg.sender != CORE_OWNER.owner():
        if msg.sender == CORE_OWNER.guardian():
            assert not is_enabled, "DFM:C Guardian can only disable"
        else:
            raise "DFM:C Not owner or guardian"


@view
@internal
def _assert_is_protocol_enabled():
    assert self.is_protocol_enabled, "DFM:C Protocol pause, close only"



@view
@internal
def _assert_caller_or_approved_delegate(account: address):
    if msg.sender != account:
        assert self.isDelegationEnabled, "DFM:C Delegation disabled"
        assert self.isApprovedDelegate[account][msg.sender], "DFM:C Delegate not approved"


@view
@internal
def _assert_below_debt_ceiling(total_debt: uint256):
    assert total_debt <= self.global_market_debt_ceiling, "DFM:C global debt ceiling"


@pure
@internal
def _assert_in_bounds(amount: int256, bounds: int256[2], is_sum: bool):
    if amount < bounds[0] or amount > bounds[1]:
        if is_sum:
            raise "DFM:C hook sum out of bounds"
        else:
            raise "DFM:C Hook caused invalid debt"


@view
@internal
def _assert_market_exists(market: address):
    assert self.market_contracts[market].collateral != empty(address), "DFM:C Invalid market"


@pure
@internal
def _uint_plus_int(initial: uint256, adjustment: int256) -> uint256:
    if adjustment < 0:
        return initial - convert(-adjustment, uint256)
    else:
        return initial + convert(adjustment, uint256)


@pure
@internal
def _adjust_loan_bounds(debt_change: int256) -> int256[2]:
    if debt_change < 0:
        # when reducing debt, hook cannot cause a debt increase
        return [min_value(int256), -debt_change]
    if debt_change > 0:
        # when increasing debt, hook cannot cause a debt reduction
        return [-debt_change, max_value(int256)]
    # when debt is unchanged, hook cannot apply any adjustment
    return empty(int256[2])


@pure
@internal
def _positive_only_bounds(debt_amount: uint256) -> int256[2]:
    # hook adjustment cannot cause debt_amount to go below 0
    return [-convert(debt_amount, int256), max_value(int256)]


@view
@internal
def _get_market_contracts_or_revert(market: address) -> MarketContracts:
    c: MarketContracts = self.market_contracts[market]

    assert c.collateral != empty(address), "DFM:C Invalid market"

    return c


@view
@internal
def _get_hook_address(hookdata: uint256) -> address:
    # hook address is stored in the upper 160 bits
    return convert(hookdata >> 96, address)


@view
@internal
def _get_hook_type(hookdata: uint256) -> HookType:
    # hook type is indicated in the three lowest bits:
    # 0b001 == VALIDATION_ONLY (cannot adjust debt)
    # 0b010 == FEE_ONLY (can only increase debt, adjustment is added to fees)
    # 0b100 == FEE_AND_REBATE (can increase and decrease debt, aggregate sum tracked in `hook_debt`)
    return convert(hookdata & 7, HookType)


@view
@internal
def _is_hook_id_active(hookdata: uint256, hook_id: HookId) -> bool:
    # hook ids are tracked from the 4th bit onward
    return hookdata & (convert(hook_id, uint256) << 3) != 0


@view
@internal
def _call_view_hooks(market: address, hook_id: HookId, calldata: Bytes[255], bounds: int256[2]) -> int256:
    debt_adjustment: int256 = 0
    for market_hooks_key in [market, empty(address)]:
        hookdata_array: DynArray[uint256, MAX_HOOKS] = self.market_hooks[market_hooks_key]
        if len(hookdata_array) == 0:
            continue

        for hookdata in hookdata_array:
            if not self._is_hook_id_active(hookdata, hook_id):
                continue

            hook: address = self._get_hook_address(hookdata)
            response: int256 = convert(raw_call(hook, calldata, max_outsize=32, is_static_call=True), int256)
            if response == 0:
                continue

            hook_type: HookType = self._get_hook_type(hookdata)
            if hook_type == HookType.VALIDATION_ONLY:
                raise "DFM:C Hook cannot adjust debt"
            if hook_type == HookType.FEE_ONLY:
                self._assert_in_bounds(response, [0, bounds[1]], False)
            else:
                self._assert_in_bounds(response, bounds, False)
                if response < 0:
                    hook_debt: uint256 = self.hook_debt[market_hooks_key][hook]
                    assert hook_debt >= convert(-response, uint256), "DFM:C Hook debt underflow"

            debt_adjustment += response

    if debt_adjustment != 0:
        self._assert_in_bounds(debt_adjustment, bounds, True)

    return debt_adjustment


@internal
def _deposit_collateral(account: address, collateral: address, amm: address, amount: uint256):
    assert ERC20(collateral).transferFrom(account, amm, amount, default_return_value=True)


@internal
def _withdraw_collateral(account: address, collateral: address, amm: address, amount: uint256):
    assert ERC20(collateral).transferFrom(amm, account, amount, default_return_value=True)


@internal
def _call_hooks(
    market: address,
    hook_id: HookId,
    calldata: Bytes[255],
    bounds: int256[2]
) -> int256:
    debt_adjustment: int256 = 0
    for market_hooks_key in [market, empty(address)]:
        hookdata_array: DynArray[uint256, MAX_HOOKS] = self.market_hooks[market_hooks_key]
        if len(hookdata_array) == 0:
            continue

        for hookdata in hookdata_array:
            if not self._is_hook_id_active(hookdata, hook_id):
                continue

            hook: address = self._get_hook_address(hookdata)
            response: int256 = convert(raw_call(hook, calldata, max_outsize=32), int256)
            if response == 0:
                continue

            hook_type: HookType = self._get_hook_type(hookdata)
            if hook_type == HookType.VALIDATION_ONLY:
                raise "DFM:C Hook cannot adjust debt"
            if hook_type == HookType.FEE_ONLY:
                self._assert_in_bounds(response, [0, bounds[1]], False)
            else:
                self._assert_in_bounds(response, bounds, False)
                self._adjust_hook_debt(market_hooks_key, hook, response)

            debt_adjustment += response

    if debt_adjustment != 0:
        self._assert_in_bounds(debt_adjustment, bounds, True)

    return debt_adjustment


@internal
def _adjust_hook_debt(market: address, hook: address, adjustment: int256):
    hook_debt: uint256 = self.hook_debt[market][hook]
    if adjustment < 0:
        assert hook_debt >= convert(-adjustment, uint256), "DFM:C Hook debt underflow"

    hook_debt = self._uint_plus_int(hook_debt, adjustment)
    total_hook_debt: uint256 = self._uint_plus_int(self.total_hook_debt, adjustment)
    self.hook_debt[market][hook] = hook_debt
    self.total_hook_debt = total_hook_debt

    log HookDebtAjustment(market, hook, adjustment, hook_debt, total_hook_debt)


@internal
def _update_rate(market: address, amm: address, mp_idx: uint256):
    # rate update is always the final action in a function, so that the
    # monetary policy has an accurate view of the current state
    mp_rate: uint256 = min(self.monetary_policies[mp_idx].rate_write(market), MAX_RATE)
    AMM(amm).set_rate(mp_rate)

Contract Security Audit

Contract ABI

API
[{"name":"AddMarket","inputs":[{"name":"collateral","type":"address","indexed":true},{"name":"market","type":"address","indexed":false},{"name":"amm","type":"address","indexed":false},{"name":"mp_idx","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetDelegateApproval","inputs":[{"name":"account","type":"address","indexed":true},{"name":"delegate","type":"address","indexed":true},{"name":"is_approved","type":"bool","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetDelegationEnabled","inputs":[{"name":"caller","type":"address","indexed":false},{"name":"is_enabled","type":"bool","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetProtocolEnabled","inputs":[{"name":"caller","type":"address","indexed":false},{"name":"is_enabled","type":"bool","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetImplementations","inputs":[{"name":"A","type":"uint256","indexed":true},{"name":"amm","type":"address","indexed":false},{"name":"market","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"AddMarketHook","inputs":[{"name":"market","type":"address","indexed":true},{"name":"hook","type":"address","indexed":true},{"name":"hook_type","type":"uint256","indexed":false},{"name":"active_hooks","type":"bool[4]","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveMarketHook","inputs":[{"name":"market","type":"address","indexed":true},{"name":"hook","type":"address","indexed":true},{"name":"hook_debt_released","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"HookDebtAjustment","inputs":[{"name":"market","type":"address","indexed":true},{"name":"hook","type":"address","indexed":true},{"name":"adjustment","type":"int256","indexed":false},{"name":"new_hook_debt","type":"uint256","indexed":false},{"name":"new_total_hook_debt","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"AddMonetaryPolicy","inputs":[{"name":"mp_idx","type":"uint256","indexed":true},{"name":"monetary_policy","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"ChangeMonetaryPolicy","inputs":[{"name":"mp_idx","type":"uint256","indexed":true},{"name":"monetary_policy","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"ChangeMonetaryPolicyForMarket","inputs":[{"name":"market","type":"address","indexed":true},{"name":"mp_idx","type":"uint256","indexed":true}],"anonymous":false,"type":"event"},{"name":"SetGlobalMarketDebtCeiling","inputs":[{"name":"debt_ceiling","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetPegKeeperRegulator","inputs":[{"name":"regulator","type":"address","indexed":false},{"name":"with_migration","type":"bool","indexed":false}],"anonymous":false,"type":"event"},{"name":"CreateLoan","inputs":[{"name":"market","type":"address","indexed":true},{"name":"account","type":"address","indexed":true},{"name":"caller","type":"address","indexed":true},{"name":"coll_amount","type":"uint256","indexed":false},{"name":"debt_amount","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"AdjustLoan","inputs":[{"name":"market","type":"address","indexed":true},{"name":"account","type":"address","indexed":true},{"name":"caller","type":"address","indexed":true},{"name":"coll_adjustment","type":"int256","indexed":false},{"name":"debt_adjustment","type":"int256","indexed":false}],"anonymous":false,"type":"event"},{"name":"CloseLoan","inputs":[{"name":"market","type":"address","indexed":true},{"name":"account","type":"address","indexed":true},{"name":"caller","type":"address","indexed":true},{"name":"coll_withdrawn","type":"uint256","indexed":false},{"name":"debt_withdrawn","type":"uint256","indexed":false},{"name":"debt_repaid","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"LiquidateLoan","inputs":[{"name":"market","type":"address","indexed":true},{"name":"liquidator","type":"address","indexed":true},{"name":"account","type":"address","indexed":true},{"name":"coll_received","type":"uint256","indexed":false},{"name":"debt_received","type":"uint256","indexed":false},{"name":"debt_repaid","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"CollectAmmFees","inputs":[{"name":"market","type":"address","indexed":true},{"name":"amm_coll_fees","type":"uint256","indexed":false},{"name":"amm_debt_fees","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"CollectFees","inputs":[{"name":"minted","type":"uint256","indexed":false},{"name":"redeemed","type":"uint256","indexed":false},{"name":"total_debt","type":"uint256","indexed":false},{"name":"fee","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"core","type":"address"},{"name":"stable","type":"address"},{"name":"monetary_policies","type":"address[]"},{"name":"debt_ceiling","type":"uint256"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_market_count","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_collateral_count","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_all_markets","inputs":[],"outputs":[{"name":"","type":"address[]"}]},{"stateMutability":"view","type":"function","name":"get_all_collaterals","inputs":[],"outputs":[{"name":"","type":"address[]"}]},{"stateMutability":"view","type":"function","name":"get_all_markets_for_collateral","inputs":[{"name":"collateral","type":"address"}],"outputs":[{"name":"","type":"address[]"}]},{"stateMutability":"view","type":"function","name":"get_market","inputs":[{"name":"collateral","type":"address"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_market","inputs":[{"name":"collateral","type":"address"},{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_amm","inputs":[{"name":"collateral","type":"address"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_amm","inputs":[{"name":"collateral","type":"address"},{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"max_borrowable","inputs":[{"name":"market","type":"address"},{"name":"coll_amount","type":"uint256"},{"name":"n_bands","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_implementations","inputs":[{"name":"A","type":"uint256"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"amm","type":"address"},{"name":"market_operator","type":"address"}]}]},{"stateMutability":"view","type":"function","name":"get_market_hooks","inputs":[{"name":"market","type":"address"}],"outputs":[{"name":"","type":"tuple[]","components":[{"name":"hooks","type":"address"},{"name":"hook_type","type":"uint256"},{"name":"active_hooks","type":"bool[4]"}]}]},{"stateMutability":"view","type":"function","name":"get_market_hook_debt","inputs":[{"name":"market","type":"address"},{"name":"hook","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_monetary_policy_for_market","inputs":[{"name":"market","type":"address"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_peg_keeper_active_debt","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"stored_admin_fees","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"on_create_loan_hook_adjustment","inputs":[{"name":"account","type":"address"},{"name":"market","type":"address"},{"name":"coll_amount","type":"uint256"},{"name":"debt_amount","type":"uint256"}],"outputs":[{"name":"","type":"int256"}]},{"stateMutability":"view","type":"function","name":"on_adjust_loan_hook_adjustment","inputs":[{"name":"account","type":"address"},{"name":"market","type":"address"},{"name":"coll_change","type":"int256"},{"name":"debt_change","type":"int256"}],"outputs":[{"name":"","type":"int256"}]},{"stateMutability":"view","type":"function","name":"on_close_loan_hook_adjustment","inputs":[{"name":"account","type":"address"},{"name":"market","type":"address"}],"outputs":[{"name":"","type":"int256"}]},{"stateMutability":"view","type":"function","name":"on_liquidate_hook_adjustment","inputs":[{"name":"caller","type":"address"},{"name":"market","type":"address"},{"name":"target","type":"address"}],"outputs":[{"name":"","type":"int256"}]},{"stateMutability":"nonpayable","type":"function","name":"setDelegateApproval","inputs":[{"name":"delegate","type":"address"},{"name":"is_approved","type":"bool"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"create_loan","inputs":[{"name":"account","type":"address"},{"name":"market","type":"address"},{"name":"coll_amount","type":"uint256"},{"name":"debt_amount","type":"uint256"},{"name":"n_bands","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"adjust_loan","inputs":[{"name":"account","type":"address"},{"name":"market","type":"address"},{"name":"coll_change","type":"int256"},{"name":"debt_change","type":"int256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"adjust_loan","inputs":[{"name":"account","type":"address"},{"name":"market","type":"address"},{"name":"coll_change","type":"int256"},{"name":"debt_change","type":"int256"},{"name":"max_active_band","type":"int256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"close_loan","inputs":[{"name":"account","type":"address"},{"name":"market","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"liquidate","inputs":[{"name":"market","type":"address"},{"name":"target","type":"address"},{"name":"min_x","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"liquidate","inputs":[{"name":"market","type":"address"},{"name":"target","type":"address"},{"name":"min_x","type":"uint256"},{"name":"frac","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"collect_fees","inputs":[{"name":"market_list","type":"address[]"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"increase_hook_debt","inputs":[{"name":"market","type":"address"},{"name":"hook","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"add_market","inputs":[{"name":"token","type":"address"},{"name":"A","type":"uint256"},{"name":"fee","type":"uint256"},{"name":"admin_fee","type":"uint256"},{"name":"oracle","type":"address"},{"name":"mp_idx","type":"uint256"},{"name":"loan_discount","type":"uint256"},{"name":"liquidation_discount","type":"uint256"},{"name":"debt_ceiling","type":"uint256"}],"outputs":[{"name":"","type":"address[2]"}]},{"stateMutability":"nonpayable","type":"function","name":"set_global_market_debt_ceiling","inputs":[{"name":"debt_ceiling","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_implementations","inputs":[{"name":"A","type":"uint256"},{"name":"market","type":"address"},{"name":"amm","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"add_market_hook","inputs":[{"name":"market","type":"address"},{"name":"hook","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"remove_market_hook","inputs":[{"name":"market","type":"address"},{"name":"hook","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"add_new_monetary_policy","inputs":[{"name":"monetary_policy","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"change_existing_monetary_policy","inputs":[{"name":"monetary_policy","type":"address"},{"name":"mp_idx","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"change_market_monetary_policy","inputs":[{"name":"market","type":"address"},{"name":"mp_idx","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_peg_keeper_regulator","inputs":[{"name":"regulator","type":"address"},{"name":"with_migration","type":"bool"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_protocol_enabled","inputs":[{"name":"is_enabled","type":"bool"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"setDelegationEnabled","inputs":[{"name":"is_enabled","type":"bool"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"STABLECOIN","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"CORE_OWNER","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"peg_keeper_regulator","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"markets","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"collaterals","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"market_contracts","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"collateral","type":"address"},{"name":"amm","type":"address"},{"name":"mp_idx","type":"uint256"}]}]},{"stateMutability":"view","type":"function","name":"monetary_policies","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"n_monetary_policies","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"global_market_debt_ceiling","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"total_debt","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"minted","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"redeemed","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"isApprovedDelegate","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"isDelegationEnabled","inputs":[],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"is_protocol_enabled","inputs":[],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"total_hook_debt","inputs":[],"outputs":[{"name":"","type":"uint256"}]}]

6151a45150346101b55760206153546000396000518060a01c6101b55760405260206153746000396000518060a01c6101b5576060526020615394600039600051600a60208261535401600039600051116101b55760208161535401600039600051600081600a81116101b55780156100a457905b60208160051b6020860101615354016000396000518060a01c6101b5578160051b60a00152600101818118610074575b50508060805250506040516151a4526060516151845260006101e0526000608051600a81116101b557801561014a57905b8060051b60a00151610200526101e0517fc52c1bf04d9533f4ddbbb056f87ebeb235891134e87667bf3ff3327ce15886e861020051610220526020610220a2610200516101e05160ff81116101b5576202000601556101e051600181018181106101b55790506101e0526001018181186100d5575b50506101e051620201065560206153b460003960005162020107557fa9c9963960181d6ed0ed8fe32c3d0085f8a7f15be99918300892a20b1c5d7ae660206153b4610200396020610200a160016202010d5560016202010c556151846101ba610000396151c4610000f35b600080fd60003560e01c60026034820660011b61511c01601e39600051565b6393a397768118613f9d573461511757602061518460403960206040f3613f9d565b63da5892fc811861005a57346151175760206151a460403960206040f35b63b12d54608118613f9d57602436103417615117576000606052610e0556613f9d565b63cd15bf4c811861009957346151175760015460405260206040f35b634f02c4208118613f9d573461511757620201095460405260206040f3613f9d565b63b1283e778118613f9d5760243610341761511757600435600254811015615117576003015460405260206040f3613f9d565b6324c1173b8118610121576024361034176151175760043562010003548110156151175762010004015460405260206040f35b632ba0840f8118613f9d57608436103417615117577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6105405261035856613f9d565b63822b7b098118613f9d57602436103417615117576004358060a01c6151175760405262020005604051602052600052604060002080546060526001810154608052600281015460a0525060606060f3613f9d565b63762e7b9281186101e8576024361034176151175760043560ff81116151175762020006015460405260206040f35b631ac186a68118610206573461511757620201115460405260206040f35b63560217428118613f9d57604436103417615117576004358060a01c615117576040526024358060a01c6151175760605262020110604051602052600052604060002080606051602052600052604060002090505460805260206080f3613f9d565b63d9049c028118610286573461511757620201065460405260206040f35b63496763ce8118613f9d57602436103417615117576102a3614efc565b60043562020107557fa9c9963960181d6ed0ed8fe32c3d0085f8a7f15be99918300892a20b1c5d7ae660043560e052602060e0a100613f9d565b634faf4b4881186102fb573461511757620201075460405260206040f35b63a46391288118613f9d5734615117576202010c5460405260206040f3613f9d565b6331dc3ca8811861033b573461511757620201085460405260206040f35b63aa5ff3c08118613f9d5760a43610341761511757608435610540525b6004358060a01c61511757610500526024358060a01c61511757610520526000546002146151175760026000556044351561039457600161039a565b60643515155b61040457600f610560527f44464d3a43204e6f206368616e676500000000000000000000000000000000006105805261056050610560518061058001601f826000031636823750506308c379a061052052602061054052601f19601f61056051011660440161053cfd5b61040c61459d565b6105005160405261041b614605565b6105205160405261042d6105c06146f9565b6105c080516105605260208101516105805260408101516105a05250610520516107005260026107205263f9c1d1816105e45260046105005161060452610520516106245260406044610644376080016105e0526105e0602081510180610740828460045afa5050506064356040526104a76106a06144ab565b6106a0805161086052602081015161088052506101a06101806101a061070060045afa506104d66106e06149e0565b6106e051606435808201828112600083121861511757905090506105c052610520516381bfcbe7610600526105005161062052604435610640526105c0516106605261054051610680526020610600608461061c6000855af161053e573d600060003e3d6000fd5b60203d10615117576106009050516105e05262020108546040526105e05160605261056a61062061479d565b6106205161060052610600516202010855606435156106e1576064357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156105b457806105c3565b80600003811461511757806000035b905060008112615117576106205260016064351215610659576202010a546106205180820182811061511757905090506202010a556020615184600039600051639dc29fac61064052336106605261062051610680526020610640604461065c6000855af1610637573d600060003e3d6000fd5b60203d1061511757610640518060011c615117576106a0526106a050506106e1565b61060051604052610668614d07565b6202010954610620518082018281106151175790509050620201095560206151846000396000516340c10f1961064052336106605261062051610680526020610640604461065c6000855af16106c3573d600060003e3d6000fd5b60203d1061511757610640518060011c615117576106a0526106a050505b60443515610788576044357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81131561071a5780610729565b80600003811461511757806000035b905060008112615117576106205260016044351215610767573360405261056051606052610580516080526106205160a052610788614e0f56610788565b3360405261056051606052610580516080526106205160a052610788614c90565b61052051604052610580516060526105a0516080526107a5614d74565b3361050051610520517f79be6dfcb3a3568b21afc806c66bcd67098197716d17923c3189da0c7973f826604435610620526105c051610640526040610620a4600360005500613f9d565b63e231bff0811861080d5734615117576202010a5460405260206040f35b6334bc68d0811861089057604436103417615117576024356060525b6004358060a01c6151175760405262020004604051602052600052604060002054606051106108605760006080526020608061088e565b6202000460405160205260005260406000206060518154811015615117576001820101905054608052602060805bf35b63c13425748118613f9d5760843610341761511757606435610540525b6004358060a01c61511757610500526024358060a01c6151175761052052600054600214615117576002600055670de0b6b3a7640000610540511115610953576013610560527f44464d3a43206672616320746f6f2068696768000000000000000000000000006105805261056050610560518061058001601f826000031636823750506308c379a061052052602061054052601f19601f61056051011660440161053cfd5b610500516040526109656105c06146f9565b6105c080516105605260208101516105805260408101516105a052506080366105c0376105005163c134257461064052336106605261052051610680526044356106a052610540516106c0526080610640608461065c6000855af16109cf573d600060003e3d6000fd5b60803d1061511757610640905080516105c05260208101516105e052604081018051610600526020810151610620525050610500516107805260086107a052637e7e3db96106645260043361068452610500516106a452610520516106c4526105e0516106e452608001610660526106606020815101806107c0828460045afa5050506105e051604052610a6461072061444b565b61072080516108e052602081015161090052506101a06101806101a061078060045afa50610a936107606149e0565b61076051610640526105e05160405261064051606052610ab461066061479d565b610660516105e0526202010a546105e05180820182811061511757905090506202010a5562020108546040526105c051606052610af261066061479d565b610660516202010855610600516105e05180828118828410021890509050610660526106605115610b7d576020615184600039600051639dc29fac61068052610580516106a052610660516106c0526020610680604461069c6000855af1610b5f573d600060003e3d6000fd5b60203d1061511757610680518060011c615117576106e0526106e050505b610600516105e05111610c06576105e051610600511115610c705760206151846000396000516323b872dd61068052610580516106a052336106c0526105e05161060051036106e0526020610680606461069c6000855af1610be4573d600060003e3d6000fd5b60203d1061511757610680518060011c61511757610700526107005050610c70565b610600516105e05103610680526020615184600039600051639dc29fac6106a052336106c052610680516106e05260206106a060446106bc6000855af1610c52573d600060003e3d6000fd5b60203d10615117576106a0518060011c615117576107005261070050505b6106205115610c9a573360405261056051606052610580516080526106205160a052610c9a614e0f565b61050051604052610580516060526105a051608052610cb7614d74565b6105205133610500517f9ef0a399defbe09357ef7431cb1cab06dd5ede64767faa82a286b5cbda5eeaf56106205161068052610600516106a0526105e0516106c0526060610680a4600360005500613f9d565b631930e8258118613f9d57604436103417615117576004358060a01c615117576040526024358060a01c615117576060526202010b604051602052600052604060002080606051602052600052604060002090505460805260206080f3613f9d565b63d2c642f28118613f9d5734615117576202010d5460405260206040f3613f9d565b638da5cb5b8118610de9573461511757602060206151a4600039600051638da5cb5b604052602060406004605c845afa610dcd573d600060003e3d6000fd5b60203d10615117576040518060a01c6151175760805260809050f35b631539838f8118610e8857604436103417615117576024356060525b6004358060a01c615117576040526202000460405160205260005260406000205460605110610e3c57600060805260206080610e86565b62020004604051602052600052604060002060605181548110156151175760018201019050546080526202000560805160205260005260406000206001810190505460a052602060a05bf35b63c0c1fe5f8118613f9d57604436103417615117576004358060a01c6151175760e0526024358060011c6151175761010052610ec2614efc565b6001546101205260e0516101205118610f3b576019610140527f44464d3a4320726567756c61746f7220756e6368616e676564000000000000006101605261014050610140518061016001601f826000031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b610100511561118d576000610140526000612160526101205163a788461461418052614080614180600461419c845afa610f7a573d600060003e3d6000fd5b60803d106151175761418051614180016101008151116151175780516000816101008111615117578015610fd057905b8060051b6020850101518060a01c615117578160051b6182400152600101818118610faa575b5050806182205250506141a0516141800161010081511161511757805160208160051b018061a240828560045afa505050506182209050805160208160051b0180610140828560045afa5050506120208101805160208160051b0180612160828560045afa505050505060006101405161010081116151175780156110a357905b8060051b610160015161418052614180516312898b1b6141a05260e0516141c052803b156151175760006141a060246141bc6000855af1611097573d600060003e3d6000fd5b50600101818118611051575b505060e05163eca6a2f6614180526040806141a052806141a0016000610140518083528060051b60008261010081116151175780156110fc57905b8060051b61016001518160051b6020880101526001018181186110de575b50508201602001915050905081019050806141c052806141a0016000612160518083528060051b600082610100811161511757801561115557905b8060051b61218001518160051b602088010152600101818118611137575b50508201602001915050905081015050803b1561511757600061418061408461419c6000855af161118b573d600060003e3d6000fd5b505b60e0516001557f7e9723534c62b7bad673d3c8d3f03b638fb6c464fe3bf0636db4e7986ec7dce860e0516101405261010051610160526040610140a100613f9d565b6356997a628118613f9d57346151175760025460405260206040f3613f9d565b6363cd5a008114600336111615613f9d573461511757620100035460405260206040f3613f9d565b637a520daa81186112805734615117576020806040528060400160006002548083528060051b60008262010000811161511757801561126c57905b80600301548160051b602088010152600101818118611252575b505082016020019150509050810190506040f35b631339051e8118613f9d57604436103417615117576004358060a01c61511757610500526024358060a01c6151175761052052600054600214615117576002600055610500516040526112d1614605565b610520516040526112e36105a06146f9565b6105a0805161054052602081015161056052604081015161058052506080366105a0376105205163656c80956106205261050051610640526080610620602461063c6000855af1611339573d600060003e3d6000fd5b60803d1061511757610620905080516105a05260208101516105c0526040810180516105e052602081015161060052505061052051610740526004610760526390ce0765610644526004610500516106645261052051610684526105c0516106a45260600161064052610640602081510180610780828460045afa5050506105c0516040526113c96106e061444b565b6106e080516108a05260208101516108c052506101a06101806101a061074060045afa506113f86107206149e0565b61072051610620526105c0516040526106205160605261141961064061479d565b610640516105c0526202010a546105c05180820182811061511757905090506202010a5562020108546040526105a05160605261145761064061479d565b6106405162020108556105e051156114ce5760206151846000396000516323b872dd61064052610560516106605233610680526105e0516106a0526020610640606461065c6000855af16114b0573d600060003e3d6000fd5b60203d1061511757610640518060011c615117576106c0526106c050505b6020615184600039600051639dc29fac6106405233610660526105c051610680526020610640604461065c6000855af161150d573d600060003e3d6000fd5b60203d1061511757610640518060011c615117576106a0526106a050506106005115611554573360405261054051606052610560516080526106005160a052611554614e0f565b610520516040526105605160605261058051608052611571614d74565b3361050051610520517fabba776d3d0b8a6980d7277a9d4c2b2d7d9ce50e6d0deac46dd8a52437869ed961060051610640526105e051610660526105c051610680526060610640a4600360005500613f9d565b638c3be907811861163157346151175760208060405280604001600062010003548083528060051b60008262010000811161511757801561161d57905b806201000401548160051b602088010152600101818118611601575b505082016020019150509050810190506040f35b630b59dfaf8118613f9d57606436103417615117576004358060a01c6151175760a0526024358060a01c6151175760c05260a051156116785760a051604052611678614e86565b6202010f60a05160205260005260406000205460e05260006005905b806101005260e0516101005118611709576012610120527f44464d3a4320556e6b6e6f776e20686f6f6b00000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6202010f60a05160205260005260406000206101005181548110156151175760018201019050546101205260c05161012051604052611749610140613fa3565b61014051186117da57600461012051604052611766610160613fc7565b6101605118156117e557601e610180527f44464d3a4320486f6f6b20646f6573206e6f7420747261636b206465627400006101a0526101805061018051806101a001601f826000031636823750506308c379a061014052602061016052601f19601f61018051011660440161015cfd6117e5565b600101818118611694575b50506020615184600039600051639dc29fac610100523361012052604435610140526020610100604461011c6000855af1611825573d600060003e3d6000fd5b60203d1061511757610100518060011c615117576101605261016050506202011060a05160205260005260406000208060c05160205260005260406000209050805460443580820182811061511757905090508155506202011154604435808201828110615117579050905062020111556202010a5460443580820182811061511757905090506202010a5500613f9d565b633a92fa8d8118613f9d57602436103417615117576004358060a01c6151175760405260208060605262020004604051602052600052604060002081606001600082548083528060051b600082610100811161511757801561193157905b806001880101548160051b602088010152600101818118611915575b5050820160200191505090509050810190506060f3613f9d565b63e9d4fa12811861196a57602436103417615117576000606052610829565b63c3c854b68118613f9d57604436103417615117576004358060a01c615117576040526024358060011c615117576060526060516202010b336020526000526040600020806040516020526000526040600020905055604051337fe259956d1d8c3e1bf78e7ed5737e2520a196a6e9e4b46474a73c00db884dbb5c60605160805260206080a300613f9d565b632538c3158118613f9d57606436103417615117576004358060a01c61511757604052620201075460605262020108546040516359e7137f60a052602060a0600460bc845afa611a4b573d600060003e3d6000fd5b60203d106151175760a0905051808201828110615117579050905060805260605160805110611a8257600060a052602060a0611af1565b606051608051808203828111615117579050905060a052604051639a49719660e0526040602461010037602060e0604460fc845afa611ac6573d600060003e3d6000fd5b60203d106151175760e090505160c05260a05160c0518082811882841002189050905060e052602060e05bf3613f9d565b63d3a763518118613f9d57602436103417615117576202010e6004356020526000526040600020805460405260018101546060525060406040f3613f9d565b63248fed2b8118611d0857602436103417615117576004358060a01c615117576060526202010f6060516020526000526040600020805460208160051b01600081601f0160051c60058111615117578015611ba457905b808501548160051b60800152600101818118611b8d575b5050505050600061012052600060805160048111615117578015611c9c57905b8060051b60a001516104405260c0366104603761044051604052611be9610520613fa3565b61052051610460526007610440511660011c6104805260006004905b8061052052600861044051610520511c1615611c3257600161052051600381116151175760051b6104a001525b600101818118611c0557505061012051600381116151175760c0810261014001610460518152610480516020820152604081016104a05181526104c05160208201526104e05160408201526105005160608201525050600181016101205250600101818118611bc4575b505060208061044052806104400160006101205180835260c0810260008260048111615117578015611cf357905b60c081026101400160c08202602088010160c08160c08460045afa505050600101818118611cca575b50508201602001915050905081019050610440f35b635f88653b8118613f9d5761012436103417615117576004358060a01c6151175760e0526084358060a01c6151175761010052611d43614efc565b67016345785d8a00006044351115611db9576012610120527f44464d3a432046656520746f6f206869676800000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b620f42406044351015611e2a576011610120527f44464d3a432046656520746f6f206c6f770000000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b670de0b6b3a76400006064351115611ea0576018610120527f44464d3a432041646d696e2066656520746f6f206869676800000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b662386f26fc1000060e4351015611f1557601a610120527f44464d3a43206c697120646973636f756e7420746f6f206c6f770000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6706f05b59d3b2000060c4351115611f8b57601c610120527f44464d3a43204c6f616e20646973636f756e7420746f6f2068696768000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60e43560c43511611ffa576020610120527f44464d3a43206c6f616e20646973636f756e743c6c697120646973636f756e746101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b620201065460a4351061206b576014610120527f44464d3a4320696e76616c6964206d705f6964780000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6101005163a035b1fe610140526020610140600461015c845afa612094573d600060003e3d6000fd5b60203d1061511757610140905051610120526101205161211457600c610140527f44464d3a432070203d3d203000000000000000000000000000000000000000006101605261014050610140518061016001601f826000031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b610120516101005163ceb7f759610140526020610140600461015c6000855af1612143573d600060003e3d6000fd5b60203d106151175761014090505118156121bd576012610180527f44464d3a43207020213d2070726963655f7700000000000000000000000000006101a0526101805061018051806101a001601f826000031636823750506308c379a061014052602061016052601f19601f61018051011660440161015cfd5b6202010e6024356020526000526040600020805461014052600181015461016052506101405161224d57601d610180527f44464d3a43204e6f20696d706c656d656e746174696f6e20666f7220410000006101a0526101805061018051806101a001601f826000031636823750506308c379a061014052602061016052601f19601f61018051011660440161015cfd5b7f602d3d8160093d39f3363d3d373d3d3d363d73000000000000000000000000006101a0526101605160601b6101b3527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006101c75260366101a06000f0801561511757610180527f602d3d8160093d39f3363d3d373d3d3d363d73000000000000000000000000006101c0526101405160601b6101d3527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006101e75260366101c06000f08015615117576101a0526101805163d13f90b46101c0526101a0516101e05260e05161020052610104356102205260c4356102405260e43561026052803b156151175760006101c060a46101dc6000855af1612372573d600060003e3d6000fd5b506101a05163728cdbca6101c052610180516101e052610100516102005260e0516102205261012051610240526040604461026037803b156151175760006101c060c46101dc6000855af16123cc573d600060003e3d6000fd5b5060025461ffff81116151175761018051816003015560018101600255506202000460e05160205260005260406000205461242457620100035461ffff81116151175760e05181620100040155600181016201000355505b6202000460e0516020526000526040600020805460ff811161511757610180518160018401015560018101825550506202000561018051602052600052604060002060e05181556101a051600182015560a43560028201555060e0517f11bde9719002acc56e38889ee650bb993138c9e08678d8ba4ddd743825e00d41610180516101c0526101a0516101e05260a4356102005260606101c0a2610180516101c0526101a0516101e05260406101c0f3613f9d565b632543eb328118613f9d57602436103417615117576004358060a01c6151175760405262020005604051602052600052604060002080546060526001810154608052600281015460a0525060605161253957600060c052602060c0612552565b60a05160ff81116151175762020006015460c052602060c05bf3613f9d565b6375d2ed088118613f9d573461511757600154604052604051612583576000606052602060606125b7565b602060405163305b4d6c606052602060606004607c845afa6125aa573d600060003e3d6000fd5b60203d1061511757606090505bf3613f9d565b6369ab47b8811861261457346151175762020108546202010a548082018281106151175790509050620201095480820382811161511757905090506202011154808203828111615117579050905060405260206040f35b635da5f18c8118613f9d57602436103417615117576004358060011c615117576101605261016051604052612647614faa565b610160516202010d557f2b5d179d82230ba43503598d00077c0cc165d285bbdf1e763ee4584b9e49561b3361018052610160516101a0526040610180a100613f9d565b632f4b9e4b8118613f9d57608436103417615117576004358060a01c615117576104a0526024358060a01c615117576104c05260206104c0516106005260016106205263d0ab1c8a6104e45260046104a051610504526104c0516105245260406044610544376080016104e0526104e0602081510180610640828460045afa50505060643560405261271d6105a061444b565b6105a0805161076052602081015161078052506101a06101006101a061060060045afa5061274c6105e06140c0565b6105e0f3613f9d565b6305d9d3a28118613f9d57608436103417615117576004358060a01c615117576104a0526024358060a01c615117576104c05260206104c05161060052600261062052632406a3506104e45260046104a051610504526104c0516105245260406044610544376080016104e0526104e0602081510180610640828460045afa5050506064356040526127e86105a06144ab565b6105a0805161076052602081015161078052506101a06101006101a061060060045afa506128176105e06140c0565b6105e0f3613f9d565b635af8e5fc811861292b57604436103417615117576004358060a01c615117576104a0526024358060a01c615117576104c0526104c051639b6c56ec610500526104a051610520526020610500602461051c845afa612884573d600060003e3d6000fd5b60203d10615117576105009050516104e05260206104c05161060052600461062052631baf02036105045260046104a051610524526104c051610544526104e0516105645260600161050052610500602081510180610640828460045afa5050506104e0516040526128f76105a061444b565b6105a0805161076052602081015161078052506101a06101006101a061060060045afa506129266105e06140c0565b6105e0f35b63e6932ac88118613f9d57604436103417615117576004358060a01c6151175761010052612957614efc565b61010051604052612966614e86565b6202010654602435106129d7576014610120527f44464d3a4320696e76616c6964206d705f6964780000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6024356202000561010051602052600052604060002060028101905055610100516040526202000561010051602052600052604060002060018101905054606052602435608052612a26614d74565b602435610100517fe2b88e5e080a641a4620ca23c04dcb08bf9cc02097b43e0507d510e1262970a96000610120a300613f9d565b63166dabef8118612b7c57606436103417615117576004358060a01c615117576104a0526024358060a01c615117576104c0526044358060a01c615117576104e0526104c051639b6c56ec610520526104e051610540526020610520602461053c845afa612acd573d600060003e3d6000fd5b60203d10615117576105209050516105005260206104c0516106405260086106605263f4a589746105245260046104a051610544526104c051610564526104e05161058452610500516105a45260800161052052610520602081510180610680828460045afa50505061050051604052612b486105e061444b565b6105e080516107a05260208101516107c052506101a06101006101a061064060045afa50612b776106206140c0565b610620f35b6326c013038118613f9d5760643610341761511757670de0b6b3a7640000610540526108ad56613f9d565b638930995f8118613f9d5760a436103417615117576004358060a01c61511757610500526024358060a01c615117576105205260005460021461511757600260005560443515612bfb576064351515612bfe565b60005b612c68576014610540527f44464d3a43203020636f6c6c206f7220646562740000000000000000000000006105605261054050610540518061056001601f826000031636823750506308c379a061050052602061052052601f19601f61054051011660440161051cfd5b612c7061459d565b61050051604052612c7f614605565b61052051604052612c916105a06146f9565b6105a080516105405260208101516105605260408101516105805250610520516106e052600161070052632f7e21a46105c4526004610500516105e452610520516106045260406044610624376080016105c0526105c0602081510180610720828460045afa505050606435604052612d0b61068061444b565b610680805161084052602081015161086052506101a06101806101a06106e060045afa50612d3a6106c06149e0565b6106c0516105a0526064356040526105a051606052612d5a6105e061479d565b6105e0516105c05233604052610540516060526105605160805260443560a052612d82614c90565b6105205163d9a39df8610600526105005161062052604435610640526105c05161066052608435610680526020610600608461061c6000855af1612dcb573d600060003e3d6000fd5b60203d10615117576106009050516105e05262020108546105e05180820182811061511757905090506106005261060051604052612e07614d07565b61060051620201085562020109546064358082018281106151175790509050620201095560206151846000396000516340c10f19610620523361064052606435610660526020610620604461063c6000855af1612e69573d600060003e3d6000fd5b60203d1061511757610620518060011c61511757610680526106805050610520516040526105605160605261058051608052612ea3614d74565b3361050051610520517fbf2742c8e657897c9f047c065e83679fdea6e8bf1a460402c3c922f800b74bf1604435610620526105c051610640526040610620a4600360005500613f9d565b636280c9ab8118613f9d576044361034176151175760043560040160ff81351161511757803560008160ff8111615117578015612f4c57905b8060051b6020850101358060a01c615117578160051b6101800152600101818118612f26575b505080610160525050600054600214615117576002600055612f6c61459d565b60206151a460003960005163b3f00674612180526020612180600461219c845afa612f9c573d600060003e3d6000fd5b60203d1061511757612180518060a01c615117576121c0526121c090505161216052614000366121803760006101605160ff81116151175780156131aa57905b8060051b61018001516161805261618051604052612ffb6162006146f9565b61620080516161a05260208101516161c05260408101516161e052506060366162003761618051631e0cfcef616260526060616260600461627c6000855af1613049573d600060003e3d6000fd5b60603d10615117576162609050805161620052602081018051616220526020810151616240525050612180516162005180820182811061511757905090506121805261622051156130fc5760206151846000396000516323b872dd616260526161c05161628052612160516162a052616220516162c0526020616260606461627c6000855af16130de573d600060003e3d6000fd5b60203d1061511757616260518060011c615117576162e0526162e050505b616240511561312957612160516040526161a0516060526161c0516080526162405160a052613129614e0f565b616180517f04dd27d55b92d68e556c87c41371d3c5ff554a0abd8ecb5cfa8ac7f917c94f3e616240516162605261622051616280526040616260a26161c0516121a05160fe81116151175760051b6121c001526161e0516121a05160fe81116151175760051b6141a0015260016121a051016121a052600101818118612fdc575b505062020108546121805180820182811061511757905090506161805261618051620201085560006161a05262020109546161c0526202010a546161e052616180516161e051808201828110615117579050905062020111548082038281116151175790509050616200526161c051616200511115613299576162005162020109556161c05161620051036161a05260206151846000396000516340c10f196162205261216051616240526161a051616260526020616220604461623c6000855af161327b573d600060003e3d6000fd5b60203d1061511757616220518060011c615117576162805261628050505b60006121a05260006101605160ff811161511757801561331557905b8060051b610180015161622052616220516040526121a05160fe81116151175760051b6121c001516060526121a05160fe81116151175760051b6141a001516080526132ff614d74565b60016121a051016121a0526001018181186132b5575b50507f1ac56d7e866e3f5ea9aa92aa11758ead39a0a5f013f3fefb0f47cb9d008edd276161c051616220526161e0516162405261618051616260526161a051616280526080616220a160206161a06003600055f3613f9d565b63a8d706ed8118613f9d57606436103417615117576024358060a01c6151175760e0526044358060a01c61511757610100526133a8614efc565b600260043510156133ba5760006133c3565b61271060043511155b61342b576016610120527f44464d3a432041206f75747369646520626f756e6473000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60e05161010051186134a857610100511561367157601e610120527f44464d3a43206d61746368696e6720696d706c656d656e746174696f6e7300006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd613671565b61010051156134bb5760e05115156134be565b60005b61352657601a610120527f44464d3a4320656d70747920696d706c656d656e746174696f6e0000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60043560e05163f446c1d0610120526020610120600461013c845afa613551573d600060003e3d6000fd5b60203d106151175761012090505118156135cb576018610160527f44464d3a4320696e636f7272656374206d61726b6574204100000000000000006101805261016050610160518061018001601f826000031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b6004356101005163f446c1d0610120526020610120600461013c845afa6135f7573d600060003e3d6000fd5b60203d10615117576101209050511815613671576015610160527f44464d3a4320696e636f727265637420616d6d204100000000000000000000006101805261016050610160518061018001601f826000031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b6202010e600435602052600052604060002061010051815560e0516001820155506004357fb55605b8d8e835ca6641329db445749b15ad50629b4ee079e7c8e88ea186a426610100516101205260e051610140526040610120a200613f9d565b6332edb1108118613f9d57604436103417615117576004358060a01c6151175760e0526024358060a01c615117576101005261370b614efc565b60e051156137215760e051604052613721614e86565b6202010f60e0516020526000526040600020805460208160051b01600081601f0160051c6005811161511757801561376d57905b808501548160051b6101200152600101818118613755575b505050505060036101205111156137e45760206101c0527f44464d3a43204d6178696d756d20686f6f6b20636f756e7420726561636865646101e0526101c0506101c051806101e001601f826000031636823750506308c379a06101805260206101a052601f19601f6101c051011660440161019cfd5b6000610120516004811161511757801561389757905b8060051b61014001516101c052610100516101c05160405261381d6101e0613fa3565b6101e0511861388c576018610200527f44464d3a4320486f6f6b20616c726561647920616464656400000000000000006102205261020050610200518061022001601f826000031636823750506308c379a06101c05260206101e052601f19601f6102005101166044016101dcfd5b6001018181186137fa575b5050610100516375fec5946102605260a0610260600461027c845afa6138c2573d600060003e3d6000fd5b60a03d10615117576102605161032052610280518060011c61511757610340526102a0518060011c61511757610360526102c0518060011c61511757610380526102e0518060011c615117576103a052610320905080516101c0526020810180516101e052602081015161020052604081015161022052606081015161024052505060026101c05111156139b6576017610260527f44464d3a4320496e76616c696420686f6f6b20747970650000000000000000006102805261026050610260518061028001601f826000031636823750506308c379a061022052602061024052601f19601f61026051011660440161023cfd5b60016101c0511b6102605260006004905b806102805261028051600381116151175760051b6101e0015115613a105761026051600161028051600381018181106151175790501b8082018281106151175790509050610260525b6001018181186139c75750506102605160031c613a8d57601b610280527f44464d3a43204e6f2061637469766520686f6f6b20706f696e747300000000006102a0526102805061028051806102a001601f826000031636823750506308c379a061024052602061026052601f19601f61028051011660440161025cfd5b610260516101005160601b8082018281106151175790509050610260526202010f60e051602052600052604060002080546003811161511757610260518160018401015560018101825550506101005160e0517f87e627cd8c8921af9587fe2e6d32b3cdaa8d64ede0faf1f3b5b67920e03d33406101c051610280526101e0516102a052610200516102c052610220516102e052610240516103005260a0610280a300613f9d565b63e39001ce8118613f9d57604436103417615117576004358060a01c61511757610180526024358060a01c615117576101a052613b70614efc565b6101805115613b885761018051604052613b88614e86565b6202010f610180516020526000526040600020546101c05260006005905b806101e0526101c0516101e05118613c1e576012610200527f44464d3a4320556e6b6e6f776e20686f6f6b00000000000000000000000000006102205261020050610200518061022001601f826000031636823750506308c379a06101c05260206101e052601f19601f6102005101166044016101dcfd5b6101a0516202010f6101805160205260005260406000206101e0518154811015615117576001820101905054604052613c58610200613fa3565b6102005114613c6657613ce2565b6202010f61018051602052600052604060002060018154801561511757038082558060018301019050905054610200526101c051600181038181116151175790506101e0511015613ced57610200516202010f6101805160205260005260406000206101e0518154811015615117576001820101905055613ced565b600101818118613ba6575b505062020110610180516020526000526040600020806101a05160205260005260406000209050546101e0526101e05115613d7157610180516080526101a05160a0526101e0518060ff1c615117577f800000000000000000000000000000000000000000000000000000000000000081146151175760000360c052613d7161483b565b6101a051610180517fd2ba1addacfcbcbc23a57b995978f1a0ef460e30f66abcadb6c70cc5c4154bd66101e051610200526020610200a300613f9d565b633e100c7e8118613f9d57602436103417615117576004358060a01c6151175760e052613dd9614efc565b62020106546101005260e0516101005160ff81116151175762020006015561010051600181018181106151175790506202010655610100517fc52c1bf04d9533f4ddbbb056f87ebeb235891134e87667bf3ff3327ce15886e860e051610120526020610120a200613f9d565b63e1eacc8f8118613f9d57604436103417615117576004358060a01c6151175760e052613e70614efc565b620201065460243510613ee0576014610100527f44464d3a4320696e76616c6964206d705f6964780000000000000000000000006101205261010050610100518061012001601f826000031636823750506308c379a060c052602060e052601f19601f61010051011660440160dcfd5b60e05160243560ff8111615117576202000601556024357f360fb1b952a743afe4c3396fc3229723a4ebd3cb2a3cefa111bb00bb0ff7589860e051610100526020610100a200613f9d565b63f28699fa8118613f9d57602436103417615117576004358060011c615117576101605261016051604052613f5e614faa565b610160516202010c557ff8d26d1a3a211bb38503963aa0898e2a241f291063df5c514d4ed06ae14b97ee3361018052610160516101a0526040610180a1005b60006000fd5b60405160601c8060a01c61511757815250565b60605160031b604051161515815250565b6007604051168060031c61511757815250565b60605160405112613ff15760805160405113613ff4565b60015b156140be5760a05161406157601e60c0527f44464d3a4320486f6f6b2063617573656420696e76616c69642064656274000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd6140be565b601c60c0527f44464d3a4320686f6f6b2073756d206f7574206f6620626f756e64730000000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b565b60006102a052610100516102e05260006103005260006002905b8060051b6102e001516102c0526202010f6102c0516020526000526040600020805460208160051b01600081601f0160051c6005811161511757801561413457905b808501548160051b610320015260010181811861411c575b5050505050610320516141465761440b565b6000610320516004811161511757801561440857905b8060051b61034001516103c0526103c051604052610120516060526141826103e0613fb6565b6103e05161418f576143fd565b6103c0516040526141a1610400613fa3565b610400516103e0526103e0515a610140506020610440610140516101608585fa905090506141d4573d600060003e3d6000fd5b3d602081183d6020100218610420526104206020810151815160200360031b1d90506104005261040051614207576143fd565b6103c051604052614219610440613fc7565b61044051610420526001610420511861429257601d610440527f44464d3a4320486f6f6b2063616e6e6f742061646a75737420646562740000006104605261044050610440518061046001601f826000031636823750506308c379a061040052602061042052601f19601f61044051011660440161041cfd5b600261042051186142c15761040051604052600060605261028051608052600060a0526143dd613fda566143dd565b610400516040526102605160605261028051608052600060a0526142e3613fda565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61040051136143dd57620201106102c0516020526000526040600020806103e051602052600052604060002090505461044052610400517f800000000000000000000000000000000000000000000000000000000000000081146151175760000360008112615117576104405110156143dd576019610460527f44464d3a4320486f6f6b206465627420756e646572666c6f77000000000000006104805261046050610460518061048001601f826000031636823750506308c379a061042052602061044052601f19601f61046051011660440161043cfd5b6102a05161040051808201828112600083121861511757905090506102a0525b60010181811861415c575b50505b6001018181186140da5750506102a05115614442576102a0516040526102605160605261028051608052600160a052614442613fda565b6102a051815250565b6040518060ff1c615117577f800000000000000000000000000000000000000000000000000000000000000081146151175760000381527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602082015250565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040511361452f577f800000000000000000000000000000000000000000000000000000000000000081526040517f800000000000000000000000000000000000000000000000000000000000000081146151175760000360208201525061459b565b600160405112614594576040517f800000000000000000000000000000000000000000000000000000000000000081146151175760000381527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208201525061459b565b6040368237505b565b6202010d546146035760206040527f44464d3a432050726f746f636f6c2070617573652c20636c6f7365206f6e6c7960605260405060405180606001601f826000031636823750506308c379a06000526020602052601f19601f6040510116604401601cfd5b565b60405133146146f7576202010c546146745760196060527f44464d3a432044656c65676174696f6e2064697361626c65640000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6202010b6040516020526000526040600020803360205260005260406000209050546146f757601b6060527f44464d3a432044656c6567617465206e6f7420617070726f766564000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b565b62020005604051602052600052604060002080546060526001810154608052600281015460a0525060605161478557601460c0527f44464d3a4320496e76616c6964206d61726b657400000000000000000000000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b6060518152608051602082015260a051604082015250565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605113156147ef576040516060516000811261511757808201828110615117579050905081525061483956614839565b6040516060517f8000000000000000000000000000000000000000000000000000000000000000811461511757600003600081126151175780820382811161511757905090508152505b565b6202011060805160205260005260406000208060a051602052600052604060002090505460e0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60c0511361492c5760c0517f8000000000000000000000000000000000000000000000000000000000000000811461511757600003600081126151175760e051101561492c576019610100527f44464d3a4320486f6f6b206465627420756e646572666c6f77000000000000006101205261010050610100518061012001601f826000031636823750506308c379a060c052602060e052601f19601f61010051011660440160dcfd5b60e05160405260c05160605261494361010061479d565b6101005160e052620201115460405260c05160605261496361012061479d565b610120516101005260e0516202011060805160205260005260406000208060a051602052600052604060002090505561010051620201115560a0516080517fce64682be365129d68e82326ad253f548f1f36f36772ea07298122b16c4fbdb260c0516101205260e0516101405261010051610160526060610120a3565b600061032052610180516103605260006103805260006002905b8060051b6103600151610340526202010f610340516020526000526040600020805460208160051b01600081601f0160051c60058111615117578015614a5457905b808501548160051b6103a00152600101818118614a3c575b50505050506103a051614a6657614c50565b60006103a05160048111615117578015614c4d57905b8060051b6103c0015161044052610440516040526101a051606052614aa2610460613fb6565b61046051614aaf57614c42565b61044051604052614ac1610480613fa3565b6104805161046052610460515a6101c05060206104c06101c0516101e060008686f190509050614af6573d600060003e3d6000fd5b3d602081183d60201002186104a0526104a06020810151815160200360031b1d90506104805261048051614b2957614c42565b61044051604052614b3b6104c0613fc7565b6104c0516104a05260016104a05118614bb457601d6104c0527f44464d3a4320486f6f6b2063616e6e6f742061646a75737420646562740000006104e0526104c0506104c051806104e001601f826000031636823750506308c379a06104805260206104a052601f19601f6104c051011660440161049cfd5b60026104a05118614be35761048051604052600060605261030051608052600060a052614c22613fda56614c22565b610480516040526102e05160605261030051608052600060a052614c05613fda565b610340516080526104605160a0526104805160c052614c2261483b565b610320516104805180820182811260008312186151175790509050610320525b600101818118614a7c575b50505b6001018181186149fa5750506103205115614c8757610320516040526102e05160605261030051608052600160a052614c87613fda565b61032051815250565b6060516323b872dd60c05260405160e0526080516101005260a05161012052602060c0606460dc6000855af1614ccb573d600060003e3d6000fd5b3d614ce257803b1561511757600161014052614cfa565b60203d106151175760c0518060011c61511757610140525b6101409050511561511757565b62020107546040511115614d725760196060527f44464d3a4320676c6f62616c2064656274206365696c696e670000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b565b60805160ff81116151175762020006015463bdb09f2e60c05260405160e052602060c0602460dc6000855af1614daf573d600060003e3d6000fd5b60203d106151175760c0905051640a3c2abcef818118640a3c2abcef83100218905060a05260605163d4387a9960c05260a05160e052602060c0602460dc6000855af1614e01573d600060003e3d6000fd5b60203d106151175760c05050565b6060516323b872dd60c05260805160e0526040516101005260a05161012052602060c0606460dc6000855af1614e4a573d600060003e3d6000fd5b3d614e6157803b1561511757600161014052614e79565b60203d106151175760c0518060011c61511757610140525b6101409050511561511757565b62020005604051602052600052604060002054614efa5760146060527f44464d3a4320496e76616c6964206d61726b657400000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b565b60206151a4600039600051638da5cb5b604052602060406004605c845afa614f29573d600060003e3d6000fd5b60203d10615117576040518060a01c615117576080526080905051331815614fa857601060a0527f44464d3a43204f6e6c79206f776e65720000000000000000000000000000000060c05260a05060a0518060c001601f826000031636823750506308c379a06060526020608052601f19601f60a0510116604401607cfd5b565b60206151a4600039600051638da5cb5b606052602060606004607c845afa614fd7573d600060003e3d6000fd5b60203d10615117576060518060a01c6151175760a05260a090505133146151155760206151a460003960005163452a932060c052602060c0600460dc845afa615025573d600060003e3d6000fd5b60203d106151175760c0518060a01c615117576101005261010090505133186150b8576040511561511557601f610120527f44464d3a4320477561726469616e2063616e206f6e6c792064697361626c65006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd615115565b601b60c0527f44464d3a43204e6f74206f776e6572206f7220677561726469616e000000000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b565b600080fd031d18b70d6c15c436d119f63dae3e453f9d3f9d02682ba702dd3f9d01b91b3611ef3f9d12170d8e003c3f9d3f2b00ee25bd336e2755268a25583f9d194b2eed3f9d1af73f9d3f9d3f9d3f9d11cf3f9d28203f9d3b353f9d07ef0d0a001a2a5a007d016424d900bb841951848118681840a16576797065728300030a0016000000000000000000000000052fa9d3f0e2e009f038191fb91defeace8fd8500000000000000000000000008f25db5ff53b9bb16669b8e59b2f784e9eaac43e000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000052b7d2dcc80cd2e4000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000094c317b4c07daeaf2eed8f587bbd8e1bf180dd4d

Deployed Bytecode

0x60003560e01c60026034820660011b61511c01601e39600051565b6393a397768118613f9d573461511757602061518460403960206040f3613f9d565b63da5892fc811861005a57346151175760206151a460403960206040f35b63b12d54608118613f9d57602436103417615117576000606052610e0556613f9d565b63cd15bf4c811861009957346151175760015460405260206040f35b634f02c4208118613f9d573461511757620201095460405260206040f3613f9d565b63b1283e778118613f9d5760243610341761511757600435600254811015615117576003015460405260206040f3613f9d565b6324c1173b8118610121576024361034176151175760043562010003548110156151175762010004015460405260206040f35b632ba0840f8118613f9d57608436103417615117577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6105405261035856613f9d565b63822b7b098118613f9d57602436103417615117576004358060a01c6151175760405262020005604051602052600052604060002080546060526001810154608052600281015460a0525060606060f3613f9d565b63762e7b9281186101e8576024361034176151175760043560ff81116151175762020006015460405260206040f35b631ac186a68118610206573461511757620201115460405260206040f35b63560217428118613f9d57604436103417615117576004358060a01c615117576040526024358060a01c6151175760605262020110604051602052600052604060002080606051602052600052604060002090505460805260206080f3613f9d565b63d9049c028118610286573461511757620201065460405260206040f35b63496763ce8118613f9d57602436103417615117576102a3614efc565b60043562020107557fa9c9963960181d6ed0ed8fe32c3d0085f8a7f15be99918300892a20b1c5d7ae660043560e052602060e0a100613f9d565b634faf4b4881186102fb573461511757620201075460405260206040f35b63a46391288118613f9d5734615117576202010c5460405260206040f3613f9d565b6331dc3ca8811861033b573461511757620201085460405260206040f35b63aa5ff3c08118613f9d5760a43610341761511757608435610540525b6004358060a01c61511757610500526024358060a01c61511757610520526000546002146151175760026000556044351561039457600161039a565b60643515155b61040457600f610560527f44464d3a43204e6f206368616e676500000000000000000000000000000000006105805261056050610560518061058001601f826000031636823750506308c379a061052052602061054052601f19601f61056051011660440161053cfd5b61040c61459d565b6105005160405261041b614605565b6105205160405261042d6105c06146f9565b6105c080516105605260208101516105805260408101516105a05250610520516107005260026107205263f9c1d1816105e45260046105005161060452610520516106245260406044610644376080016105e0526105e0602081510180610740828460045afa5050506064356040526104a76106a06144ab565b6106a0805161086052602081015161088052506101a06101806101a061070060045afa506104d66106e06149e0565b6106e051606435808201828112600083121861511757905090506105c052610520516381bfcbe7610600526105005161062052604435610640526105c0516106605261054051610680526020610600608461061c6000855af161053e573d600060003e3d6000fd5b60203d10615117576106009050516105e05262020108546040526105e05160605261056a61062061479d565b6106205161060052610600516202010855606435156106e1576064357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156105b457806105c3565b80600003811461511757806000035b905060008112615117576106205260016064351215610659576202010a546106205180820182811061511757905090506202010a556020615184600039600051639dc29fac61064052336106605261062051610680526020610640604461065c6000855af1610637573d600060003e3d6000fd5b60203d1061511757610640518060011c615117576106a0526106a050506106e1565b61060051604052610668614d07565b6202010954610620518082018281106151175790509050620201095560206151846000396000516340c10f1961064052336106605261062051610680526020610640604461065c6000855af16106c3573d600060003e3d6000fd5b60203d1061511757610640518060011c615117576106a0526106a050505b60443515610788576044357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81131561071a5780610729565b80600003811461511757806000035b905060008112615117576106205260016044351215610767573360405261056051606052610580516080526106205160a052610788614e0f56610788565b3360405261056051606052610580516080526106205160a052610788614c90565b61052051604052610580516060526105a0516080526107a5614d74565b3361050051610520517f79be6dfcb3a3568b21afc806c66bcd67098197716d17923c3189da0c7973f826604435610620526105c051610640526040610620a4600360005500613f9d565b63e231bff0811861080d5734615117576202010a5460405260206040f35b6334bc68d0811861089057604436103417615117576024356060525b6004358060a01c6151175760405262020004604051602052600052604060002054606051106108605760006080526020608061088e565b6202000460405160205260005260406000206060518154811015615117576001820101905054608052602060805bf35b63c13425748118613f9d5760843610341761511757606435610540525b6004358060a01c61511757610500526024358060a01c6151175761052052600054600214615117576002600055670de0b6b3a7640000610540511115610953576013610560527f44464d3a43206672616320746f6f2068696768000000000000000000000000006105805261056050610560518061058001601f826000031636823750506308c379a061052052602061054052601f19601f61056051011660440161053cfd5b610500516040526109656105c06146f9565b6105c080516105605260208101516105805260408101516105a052506080366105c0376105005163c134257461064052336106605261052051610680526044356106a052610540516106c0526080610640608461065c6000855af16109cf573d600060003e3d6000fd5b60803d1061511757610640905080516105c05260208101516105e052604081018051610600526020810151610620525050610500516107805260086107a052637e7e3db96106645260043361068452610500516106a452610520516106c4526105e0516106e452608001610660526106606020815101806107c0828460045afa5050506105e051604052610a6461072061444b565b61072080516108e052602081015161090052506101a06101806101a061078060045afa50610a936107606149e0565b61076051610640526105e05160405261064051606052610ab461066061479d565b610660516105e0526202010a546105e05180820182811061511757905090506202010a5562020108546040526105c051606052610af261066061479d565b610660516202010855610600516105e05180828118828410021890509050610660526106605115610b7d576020615184600039600051639dc29fac61068052610580516106a052610660516106c0526020610680604461069c6000855af1610b5f573d600060003e3d6000fd5b60203d1061511757610680518060011c615117576106e0526106e050505b610600516105e05111610c06576105e051610600511115610c705760206151846000396000516323b872dd61068052610580516106a052336106c0526105e05161060051036106e0526020610680606461069c6000855af1610be4573d600060003e3d6000fd5b60203d1061511757610680518060011c61511757610700526107005050610c70565b610600516105e05103610680526020615184600039600051639dc29fac6106a052336106c052610680516106e05260206106a060446106bc6000855af1610c52573d600060003e3d6000fd5b60203d10615117576106a0518060011c615117576107005261070050505b6106205115610c9a573360405261056051606052610580516080526106205160a052610c9a614e0f565b61050051604052610580516060526105a051608052610cb7614d74565b6105205133610500517f9ef0a399defbe09357ef7431cb1cab06dd5ede64767faa82a286b5cbda5eeaf56106205161068052610600516106a0526105e0516106c0526060610680a4600360005500613f9d565b631930e8258118613f9d57604436103417615117576004358060a01c615117576040526024358060a01c615117576060526202010b604051602052600052604060002080606051602052600052604060002090505460805260206080f3613f9d565b63d2c642f28118613f9d5734615117576202010d5460405260206040f3613f9d565b638da5cb5b8118610de9573461511757602060206151a4600039600051638da5cb5b604052602060406004605c845afa610dcd573d600060003e3d6000fd5b60203d10615117576040518060a01c6151175760805260809050f35b631539838f8118610e8857604436103417615117576024356060525b6004358060a01c615117576040526202000460405160205260005260406000205460605110610e3c57600060805260206080610e86565b62020004604051602052600052604060002060605181548110156151175760018201019050546080526202000560805160205260005260406000206001810190505460a052602060a05bf35b63c0c1fe5f8118613f9d57604436103417615117576004358060a01c6151175760e0526024358060011c6151175761010052610ec2614efc565b6001546101205260e0516101205118610f3b576019610140527f44464d3a4320726567756c61746f7220756e6368616e676564000000000000006101605261014050610140518061016001601f826000031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b610100511561118d576000610140526000612160526101205163a788461461418052614080614180600461419c845afa610f7a573d600060003e3d6000fd5b60803d106151175761418051614180016101008151116151175780516000816101008111615117578015610fd057905b8060051b6020850101518060a01c615117578160051b6182400152600101818118610faa575b5050806182205250506141a0516141800161010081511161511757805160208160051b018061a240828560045afa505050506182209050805160208160051b0180610140828560045afa5050506120208101805160208160051b0180612160828560045afa505050505060006101405161010081116151175780156110a357905b8060051b610160015161418052614180516312898b1b6141a05260e0516141c052803b156151175760006141a060246141bc6000855af1611097573d600060003e3d6000fd5b50600101818118611051575b505060e05163eca6a2f6614180526040806141a052806141a0016000610140518083528060051b60008261010081116151175780156110fc57905b8060051b61016001518160051b6020880101526001018181186110de575b50508201602001915050905081019050806141c052806141a0016000612160518083528060051b600082610100811161511757801561115557905b8060051b61218001518160051b602088010152600101818118611137575b50508201602001915050905081015050803b1561511757600061418061408461419c6000855af161118b573d600060003e3d6000fd5b505b60e0516001557f7e9723534c62b7bad673d3c8d3f03b638fb6c464fe3bf0636db4e7986ec7dce860e0516101405261010051610160526040610140a100613f9d565b6356997a628118613f9d57346151175760025460405260206040f3613f9d565b6363cd5a008114600336111615613f9d573461511757620100035460405260206040f3613f9d565b637a520daa81186112805734615117576020806040528060400160006002548083528060051b60008262010000811161511757801561126c57905b80600301548160051b602088010152600101818118611252575b505082016020019150509050810190506040f35b631339051e8118613f9d57604436103417615117576004358060a01c61511757610500526024358060a01c6151175761052052600054600214615117576002600055610500516040526112d1614605565b610520516040526112e36105a06146f9565b6105a0805161054052602081015161056052604081015161058052506080366105a0376105205163656c80956106205261050051610640526080610620602461063c6000855af1611339573d600060003e3d6000fd5b60803d1061511757610620905080516105a05260208101516105c0526040810180516105e052602081015161060052505061052051610740526004610760526390ce0765610644526004610500516106645261052051610684526105c0516106a45260600161064052610640602081510180610780828460045afa5050506105c0516040526113c96106e061444b565b6106e080516108a05260208101516108c052506101a06101806101a061074060045afa506113f86107206149e0565b61072051610620526105c0516040526106205160605261141961064061479d565b610640516105c0526202010a546105c05180820182811061511757905090506202010a5562020108546040526105a05160605261145761064061479d565b6106405162020108556105e051156114ce5760206151846000396000516323b872dd61064052610560516106605233610680526105e0516106a0526020610640606461065c6000855af16114b0573d600060003e3d6000fd5b60203d1061511757610640518060011c615117576106c0526106c050505b6020615184600039600051639dc29fac6106405233610660526105c051610680526020610640604461065c6000855af161150d573d600060003e3d6000fd5b60203d1061511757610640518060011c615117576106a0526106a050506106005115611554573360405261054051606052610560516080526106005160a052611554614e0f565b610520516040526105605160605261058051608052611571614d74565b3361050051610520517fabba776d3d0b8a6980d7277a9d4c2b2d7d9ce50e6d0deac46dd8a52437869ed961060051610640526105e051610660526105c051610680526060610640a4600360005500613f9d565b638c3be907811861163157346151175760208060405280604001600062010003548083528060051b60008262010000811161511757801561161d57905b806201000401548160051b602088010152600101818118611601575b505082016020019150509050810190506040f35b630b59dfaf8118613f9d57606436103417615117576004358060a01c6151175760a0526024358060a01c6151175760c05260a051156116785760a051604052611678614e86565b6202010f60a05160205260005260406000205460e05260006005905b806101005260e0516101005118611709576012610120527f44464d3a4320556e6b6e6f776e20686f6f6b00000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6202010f60a05160205260005260406000206101005181548110156151175760018201019050546101205260c05161012051604052611749610140613fa3565b61014051186117da57600461012051604052611766610160613fc7565b6101605118156117e557601e610180527f44464d3a4320486f6f6b20646f6573206e6f7420747261636b206465627400006101a0526101805061018051806101a001601f826000031636823750506308c379a061014052602061016052601f19601f61018051011660440161015cfd6117e5565b600101818118611694575b50506020615184600039600051639dc29fac610100523361012052604435610140526020610100604461011c6000855af1611825573d600060003e3d6000fd5b60203d1061511757610100518060011c615117576101605261016050506202011060a05160205260005260406000208060c05160205260005260406000209050805460443580820182811061511757905090508155506202011154604435808201828110615117579050905062020111556202010a5460443580820182811061511757905090506202010a5500613f9d565b633a92fa8d8118613f9d57602436103417615117576004358060a01c6151175760405260208060605262020004604051602052600052604060002081606001600082548083528060051b600082610100811161511757801561193157905b806001880101548160051b602088010152600101818118611915575b5050820160200191505090509050810190506060f3613f9d565b63e9d4fa12811861196a57602436103417615117576000606052610829565b63c3c854b68118613f9d57604436103417615117576004358060a01c615117576040526024358060011c615117576060526060516202010b336020526000526040600020806040516020526000526040600020905055604051337fe259956d1d8c3e1bf78e7ed5737e2520a196a6e9e4b46474a73c00db884dbb5c60605160805260206080a300613f9d565b632538c3158118613f9d57606436103417615117576004358060a01c61511757604052620201075460605262020108546040516359e7137f60a052602060a0600460bc845afa611a4b573d600060003e3d6000fd5b60203d106151175760a0905051808201828110615117579050905060805260605160805110611a8257600060a052602060a0611af1565b606051608051808203828111615117579050905060a052604051639a49719660e0526040602461010037602060e0604460fc845afa611ac6573d600060003e3d6000fd5b60203d106151175760e090505160c05260a05160c0518082811882841002189050905060e052602060e05bf3613f9d565b63d3a763518118613f9d57602436103417615117576202010e6004356020526000526040600020805460405260018101546060525060406040f3613f9d565b63248fed2b8118611d0857602436103417615117576004358060a01c615117576060526202010f6060516020526000526040600020805460208160051b01600081601f0160051c60058111615117578015611ba457905b808501548160051b60800152600101818118611b8d575b5050505050600061012052600060805160048111615117578015611c9c57905b8060051b60a001516104405260c0366104603761044051604052611be9610520613fa3565b61052051610460526007610440511660011c6104805260006004905b8061052052600861044051610520511c1615611c3257600161052051600381116151175760051b6104a001525b600101818118611c0557505061012051600381116151175760c0810261014001610460518152610480516020820152604081016104a05181526104c05160208201526104e05160408201526105005160608201525050600181016101205250600101818118611bc4575b505060208061044052806104400160006101205180835260c0810260008260048111615117578015611cf357905b60c081026101400160c08202602088010160c08160c08460045afa505050600101818118611cca575b50508201602001915050905081019050610440f35b635f88653b8118613f9d5761012436103417615117576004358060a01c6151175760e0526084358060a01c6151175761010052611d43614efc565b67016345785d8a00006044351115611db9576012610120527f44464d3a432046656520746f6f206869676800000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b620f42406044351015611e2a576011610120527f44464d3a432046656520746f6f206c6f770000000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b670de0b6b3a76400006064351115611ea0576018610120527f44464d3a432041646d696e2066656520746f6f206869676800000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b662386f26fc1000060e4351015611f1557601a610120527f44464d3a43206c697120646973636f756e7420746f6f206c6f770000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6706f05b59d3b2000060c4351115611f8b57601c610120527f44464d3a43204c6f616e20646973636f756e7420746f6f2068696768000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60e43560c43511611ffa576020610120527f44464d3a43206c6f616e20646973636f756e743c6c697120646973636f756e746101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b620201065460a4351061206b576014610120527f44464d3a4320696e76616c6964206d705f6964780000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6101005163a035b1fe610140526020610140600461015c845afa612094573d600060003e3d6000fd5b60203d1061511757610140905051610120526101205161211457600c610140527f44464d3a432070203d3d203000000000000000000000000000000000000000006101605261014050610140518061016001601f826000031636823750506308c379a061010052602061012052601f19601f61014051011660440161011cfd5b610120516101005163ceb7f759610140526020610140600461015c6000855af1612143573d600060003e3d6000fd5b60203d106151175761014090505118156121bd576012610180527f44464d3a43207020213d2070726963655f7700000000000000000000000000006101a0526101805061018051806101a001601f826000031636823750506308c379a061014052602061016052601f19601f61018051011660440161015cfd5b6202010e6024356020526000526040600020805461014052600181015461016052506101405161224d57601d610180527f44464d3a43204e6f20696d706c656d656e746174696f6e20666f7220410000006101a0526101805061018051806101a001601f826000031636823750506308c379a061014052602061016052601f19601f61018051011660440161015cfd5b7f602d3d8160093d39f3363d3d373d3d3d363d73000000000000000000000000006101a0526101605160601b6101b3527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006101c75260366101a06000f0801561511757610180527f602d3d8160093d39f3363d3d373d3d3d363d73000000000000000000000000006101c0526101405160601b6101d3527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006101e75260366101c06000f08015615117576101a0526101805163d13f90b46101c0526101a0516101e05260e05161020052610104356102205260c4356102405260e43561026052803b156151175760006101c060a46101dc6000855af1612372573d600060003e3d6000fd5b506101a05163728cdbca6101c052610180516101e052610100516102005260e0516102205261012051610240526040604461026037803b156151175760006101c060c46101dc6000855af16123cc573d600060003e3d6000fd5b5060025461ffff81116151175761018051816003015560018101600255506202000460e05160205260005260406000205461242457620100035461ffff81116151175760e05181620100040155600181016201000355505b6202000460e0516020526000526040600020805460ff811161511757610180518160018401015560018101825550506202000561018051602052600052604060002060e05181556101a051600182015560a43560028201555060e0517f11bde9719002acc56e38889ee650bb993138c9e08678d8ba4ddd743825e00d41610180516101c0526101a0516101e05260a4356102005260606101c0a2610180516101c0526101a0516101e05260406101c0f3613f9d565b632543eb328118613f9d57602436103417615117576004358060a01c6151175760405262020005604051602052600052604060002080546060526001810154608052600281015460a0525060605161253957600060c052602060c0612552565b60a05160ff81116151175762020006015460c052602060c05bf3613f9d565b6375d2ed088118613f9d573461511757600154604052604051612583576000606052602060606125b7565b602060405163305b4d6c606052602060606004607c845afa6125aa573d600060003e3d6000fd5b60203d1061511757606090505bf3613f9d565b6369ab47b8811861261457346151175762020108546202010a548082018281106151175790509050620201095480820382811161511757905090506202011154808203828111615117579050905060405260206040f35b635da5f18c8118613f9d57602436103417615117576004358060011c615117576101605261016051604052612647614faa565b610160516202010d557f2b5d179d82230ba43503598d00077c0cc165d285bbdf1e763ee4584b9e49561b3361018052610160516101a0526040610180a100613f9d565b632f4b9e4b8118613f9d57608436103417615117576004358060a01c615117576104a0526024358060a01c615117576104c05260206104c0516106005260016106205263d0ab1c8a6104e45260046104a051610504526104c0516105245260406044610544376080016104e0526104e0602081510180610640828460045afa50505060643560405261271d6105a061444b565b6105a0805161076052602081015161078052506101a06101006101a061060060045afa5061274c6105e06140c0565b6105e0f3613f9d565b6305d9d3a28118613f9d57608436103417615117576004358060a01c615117576104a0526024358060a01c615117576104c05260206104c05161060052600261062052632406a3506104e45260046104a051610504526104c0516105245260406044610544376080016104e0526104e0602081510180610640828460045afa5050506064356040526127e86105a06144ab565b6105a0805161076052602081015161078052506101a06101006101a061060060045afa506128176105e06140c0565b6105e0f3613f9d565b635af8e5fc811861292b57604436103417615117576004358060a01c615117576104a0526024358060a01c615117576104c0526104c051639b6c56ec610500526104a051610520526020610500602461051c845afa612884573d600060003e3d6000fd5b60203d10615117576105009050516104e05260206104c05161060052600461062052631baf02036105045260046104a051610524526104c051610544526104e0516105645260600161050052610500602081510180610640828460045afa5050506104e0516040526128f76105a061444b565b6105a0805161076052602081015161078052506101a06101006101a061060060045afa506129266105e06140c0565b6105e0f35b63e6932ac88118613f9d57604436103417615117576004358060a01c6151175761010052612957614efc565b61010051604052612966614e86565b6202010654602435106129d7576014610120527f44464d3a4320696e76616c6964206d705f6964780000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b6024356202000561010051602052600052604060002060028101905055610100516040526202000561010051602052600052604060002060018101905054606052602435608052612a26614d74565b602435610100517fe2b88e5e080a641a4620ca23c04dcb08bf9cc02097b43e0507d510e1262970a96000610120a300613f9d565b63166dabef8118612b7c57606436103417615117576004358060a01c615117576104a0526024358060a01c615117576104c0526044358060a01c615117576104e0526104c051639b6c56ec610520526104e051610540526020610520602461053c845afa612acd573d600060003e3d6000fd5b60203d10615117576105209050516105005260206104c0516106405260086106605263f4a589746105245260046104a051610544526104c051610564526104e05161058452610500516105a45260800161052052610520602081510180610680828460045afa50505061050051604052612b486105e061444b565b6105e080516107a05260208101516107c052506101a06101006101a061064060045afa50612b776106206140c0565b610620f35b6326c013038118613f9d5760643610341761511757670de0b6b3a7640000610540526108ad56613f9d565b638930995f8118613f9d5760a436103417615117576004358060a01c61511757610500526024358060a01c615117576105205260005460021461511757600260005560443515612bfb576064351515612bfe565b60005b612c68576014610540527f44464d3a43203020636f6c6c206f7220646562740000000000000000000000006105605261054050610540518061056001601f826000031636823750506308c379a061050052602061052052601f19601f61054051011660440161051cfd5b612c7061459d565b61050051604052612c7f614605565b61052051604052612c916105a06146f9565b6105a080516105405260208101516105605260408101516105805250610520516106e052600161070052632f7e21a46105c4526004610500516105e452610520516106045260406044610624376080016105c0526105c0602081510180610720828460045afa505050606435604052612d0b61068061444b565b610680805161084052602081015161086052506101a06101806101a06106e060045afa50612d3a6106c06149e0565b6106c0516105a0526064356040526105a051606052612d5a6105e061479d565b6105e0516105c05233604052610540516060526105605160805260443560a052612d82614c90565b6105205163d9a39df8610600526105005161062052604435610640526105c05161066052608435610680526020610600608461061c6000855af1612dcb573d600060003e3d6000fd5b60203d10615117576106009050516105e05262020108546105e05180820182811061511757905090506106005261060051604052612e07614d07565b61060051620201085562020109546064358082018281106151175790509050620201095560206151846000396000516340c10f19610620523361064052606435610660526020610620604461063c6000855af1612e69573d600060003e3d6000fd5b60203d1061511757610620518060011c61511757610680526106805050610520516040526105605160605261058051608052612ea3614d74565b3361050051610520517fbf2742c8e657897c9f047c065e83679fdea6e8bf1a460402c3c922f800b74bf1604435610620526105c051610640526040610620a4600360005500613f9d565b636280c9ab8118613f9d576044361034176151175760043560040160ff81351161511757803560008160ff8111615117578015612f4c57905b8060051b6020850101358060a01c615117578160051b6101800152600101818118612f26575b505080610160525050600054600214615117576002600055612f6c61459d565b60206151a460003960005163b3f00674612180526020612180600461219c845afa612f9c573d600060003e3d6000fd5b60203d1061511757612180518060a01c615117576121c0526121c090505161216052614000366121803760006101605160ff81116151175780156131aa57905b8060051b61018001516161805261618051604052612ffb6162006146f9565b61620080516161a05260208101516161c05260408101516161e052506060366162003761618051631e0cfcef616260526060616260600461627c6000855af1613049573d600060003e3d6000fd5b60603d10615117576162609050805161620052602081018051616220526020810151616240525050612180516162005180820182811061511757905090506121805261622051156130fc5760206151846000396000516323b872dd616260526161c05161628052612160516162a052616220516162c0526020616260606461627c6000855af16130de573d600060003e3d6000fd5b60203d1061511757616260518060011c615117576162e0526162e050505b616240511561312957612160516040526161a0516060526161c0516080526162405160a052613129614e0f565b616180517f04dd27d55b92d68e556c87c41371d3c5ff554a0abd8ecb5cfa8ac7f917c94f3e616240516162605261622051616280526040616260a26161c0516121a05160fe81116151175760051b6121c001526161e0516121a05160fe81116151175760051b6141a0015260016121a051016121a052600101818118612fdc575b505062020108546121805180820182811061511757905090506161805261618051620201085560006161a05262020109546161c0526202010a546161e052616180516161e051808201828110615117579050905062020111548082038281116151175790509050616200526161c051616200511115613299576162005162020109556161c05161620051036161a05260206151846000396000516340c10f196162205261216051616240526161a051616260526020616220604461623c6000855af161327b573d600060003e3d6000fd5b60203d1061511757616220518060011c615117576162805261628050505b60006121a05260006101605160ff811161511757801561331557905b8060051b610180015161622052616220516040526121a05160fe81116151175760051b6121c001516060526121a05160fe81116151175760051b6141a001516080526132ff614d74565b60016121a051016121a0526001018181186132b5575b50507f1ac56d7e866e3f5ea9aa92aa11758ead39a0a5f013f3fefb0f47cb9d008edd276161c051616220526161e0516162405261618051616260526161a051616280526080616220a160206161a06003600055f3613f9d565b63a8d706ed8118613f9d57606436103417615117576024358060a01c6151175760e0526044358060a01c61511757610100526133a8614efc565b600260043510156133ba5760006133c3565b61271060043511155b61342b576016610120527f44464d3a432041206f75747369646520626f756e6473000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60e05161010051186134a857610100511561367157601e610120527f44464d3a43206d61746368696e6720696d706c656d656e746174696f6e7300006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd613671565b61010051156134bb5760e05115156134be565b60005b61352657601a610120527f44464d3a4320656d70747920696d706c656d656e746174696f6e0000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5b60043560e05163f446c1d0610120526020610120600461013c845afa613551573d600060003e3d6000fd5b60203d106151175761012090505118156135cb576018610160527f44464d3a4320696e636f7272656374206d61726b6574204100000000000000006101805261016050610160518061018001601f826000031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b6004356101005163f446c1d0610120526020610120600461013c845afa6135f7573d600060003e3d6000fd5b60203d10615117576101209050511815613671576015610160527f44464d3a4320696e636f727265637420616d6d204100000000000000000000006101805261016050610160518061018001601f826000031636823750506308c379a061012052602061014052601f19601f61016051011660440161013cfd5b6202010e600435602052600052604060002061010051815560e0516001820155506004357fb55605b8d8e835ca6641329db445749b15ad50629b4ee079e7c8e88ea186a426610100516101205260e051610140526040610120a200613f9d565b6332edb1108118613f9d57604436103417615117576004358060a01c6151175760e0526024358060a01c615117576101005261370b614efc565b60e051156137215760e051604052613721614e86565b6202010f60e0516020526000526040600020805460208160051b01600081601f0160051c6005811161511757801561376d57905b808501548160051b6101200152600101818118613755575b505050505060036101205111156137e45760206101c0527f44464d3a43204d6178696d756d20686f6f6b20636f756e7420726561636865646101e0526101c0506101c051806101e001601f826000031636823750506308c379a06101805260206101a052601f19601f6101c051011660440161019cfd5b6000610120516004811161511757801561389757905b8060051b61014001516101c052610100516101c05160405261381d6101e0613fa3565b6101e0511861388c576018610200527f44464d3a4320486f6f6b20616c726561647920616464656400000000000000006102205261020050610200518061022001601f826000031636823750506308c379a06101c05260206101e052601f19601f6102005101166044016101dcfd5b6001018181186137fa575b5050610100516375fec5946102605260a0610260600461027c845afa6138c2573d600060003e3d6000fd5b60a03d10615117576102605161032052610280518060011c61511757610340526102a0518060011c61511757610360526102c0518060011c61511757610380526102e0518060011c615117576103a052610320905080516101c0526020810180516101e052602081015161020052604081015161022052606081015161024052505060026101c05111156139b6576017610260527f44464d3a4320496e76616c696420686f6f6b20747970650000000000000000006102805261026050610260518061028001601f826000031636823750506308c379a061022052602061024052601f19601f61026051011660440161023cfd5b60016101c0511b6102605260006004905b806102805261028051600381116151175760051b6101e0015115613a105761026051600161028051600381018181106151175790501b8082018281106151175790509050610260525b6001018181186139c75750506102605160031c613a8d57601b610280527f44464d3a43204e6f2061637469766520686f6f6b20706f696e747300000000006102a0526102805061028051806102a001601f826000031636823750506308c379a061024052602061026052601f19601f61028051011660440161025cfd5b610260516101005160601b8082018281106151175790509050610260526202010f60e051602052600052604060002080546003811161511757610260518160018401015560018101825550506101005160e0517f87e627cd8c8921af9587fe2e6d32b3cdaa8d64ede0faf1f3b5b67920e03d33406101c051610280526101e0516102a052610200516102c052610220516102e052610240516103005260a0610280a300613f9d565b63e39001ce8118613f9d57604436103417615117576004358060a01c61511757610180526024358060a01c615117576101a052613b70614efc565b6101805115613b885761018051604052613b88614e86565b6202010f610180516020526000526040600020546101c05260006005905b806101e0526101c0516101e05118613c1e576012610200527f44464d3a4320556e6b6e6f776e20686f6f6b00000000000000000000000000006102205261020050610200518061022001601f826000031636823750506308c379a06101c05260206101e052601f19601f6102005101166044016101dcfd5b6101a0516202010f6101805160205260005260406000206101e0518154811015615117576001820101905054604052613c58610200613fa3565b6102005114613c6657613ce2565b6202010f61018051602052600052604060002060018154801561511757038082558060018301019050905054610200526101c051600181038181116151175790506101e0511015613ced57610200516202010f6101805160205260005260406000206101e0518154811015615117576001820101905055613ced565b600101818118613ba6575b505062020110610180516020526000526040600020806101a05160205260005260406000209050546101e0526101e05115613d7157610180516080526101a05160a0526101e0518060ff1c615117577f800000000000000000000000000000000000000000000000000000000000000081146151175760000360c052613d7161483b565b6101a051610180517fd2ba1addacfcbcbc23a57b995978f1a0ef460e30f66abcadb6c70cc5c4154bd66101e051610200526020610200a300613f9d565b633e100c7e8118613f9d57602436103417615117576004358060a01c6151175760e052613dd9614efc565b62020106546101005260e0516101005160ff81116151175762020006015561010051600181018181106151175790506202010655610100517fc52c1bf04d9533f4ddbbb056f87ebeb235891134e87667bf3ff3327ce15886e860e051610120526020610120a200613f9d565b63e1eacc8f8118613f9d57604436103417615117576004358060a01c6151175760e052613e70614efc565b620201065460243510613ee0576014610100527f44464d3a4320696e76616c6964206d705f6964780000000000000000000000006101205261010050610100518061012001601f826000031636823750506308c379a060c052602060e052601f19601f61010051011660440160dcfd5b60e05160243560ff8111615117576202000601556024357f360fb1b952a743afe4c3396fc3229723a4ebd3cb2a3cefa111bb00bb0ff7589860e051610100526020610100a200613f9d565b63f28699fa8118613f9d57602436103417615117576004358060011c615117576101605261016051604052613f5e614faa565b610160516202010c557ff8d26d1a3a211bb38503963aa0898e2a241f291063df5c514d4ed06ae14b97ee3361018052610160516101a0526040610180a1005b60006000fd5b60405160601c8060a01c61511757815250565b60605160031b604051161515815250565b6007604051168060031c61511757815250565b60605160405112613ff15760805160405113613ff4565b60015b156140be5760a05161406157601e60c0527f44464d3a4320486f6f6b2063617573656420696e76616c69642064656274000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd6140be565b601c60c0527f44464d3a4320686f6f6b2073756d206f7574206f6620626f756e64730000000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b565b60006102a052610100516102e05260006103005260006002905b8060051b6102e001516102c0526202010f6102c0516020526000526040600020805460208160051b01600081601f0160051c6005811161511757801561413457905b808501548160051b610320015260010181811861411c575b5050505050610320516141465761440b565b6000610320516004811161511757801561440857905b8060051b61034001516103c0526103c051604052610120516060526141826103e0613fb6565b6103e05161418f576143fd565b6103c0516040526141a1610400613fa3565b610400516103e0526103e0515a610140506020610440610140516101608585fa905090506141d4573d600060003e3d6000fd5b3d602081183d6020100218610420526104206020810151815160200360031b1d90506104005261040051614207576143fd565b6103c051604052614219610440613fc7565b61044051610420526001610420511861429257601d610440527f44464d3a4320486f6f6b2063616e6e6f742061646a75737420646562740000006104605261044050610440518061046001601f826000031636823750506308c379a061040052602061042052601f19601f61044051011660440161041cfd5b600261042051186142c15761040051604052600060605261028051608052600060a0526143dd613fda566143dd565b610400516040526102605160605261028051608052600060a0526142e3613fda565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61040051136143dd57620201106102c0516020526000526040600020806103e051602052600052604060002090505461044052610400517f800000000000000000000000000000000000000000000000000000000000000081146151175760000360008112615117576104405110156143dd576019610460527f44464d3a4320486f6f6b206465627420756e646572666c6f77000000000000006104805261046050610460518061048001601f826000031636823750506308c379a061042052602061044052601f19601f61046051011660440161043cfd5b6102a05161040051808201828112600083121861511757905090506102a0525b60010181811861415c575b50505b6001018181186140da5750506102a05115614442576102a0516040526102605160605261028051608052600160a052614442613fda565b6102a051815250565b6040518060ff1c615117577f800000000000000000000000000000000000000000000000000000000000000081146151175760000381527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602082015250565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040511361452f577f800000000000000000000000000000000000000000000000000000000000000081526040517f800000000000000000000000000000000000000000000000000000000000000081146151175760000360208201525061459b565b600160405112614594576040517f800000000000000000000000000000000000000000000000000000000000000081146151175760000381527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208201525061459b565b6040368237505b565b6202010d546146035760206040527f44464d3a432050726f746f636f6c2070617573652c20636c6f7365206f6e6c7960605260405060405180606001601f826000031636823750506308c379a06000526020602052601f19601f6040510116604401601cfd5b565b60405133146146f7576202010c546146745760196060527f44464d3a432044656c65676174696f6e2064697361626c65640000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6202010b6040516020526000526040600020803360205260005260406000209050546146f757601b6060527f44464d3a432044656c6567617465206e6f7420617070726f766564000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b565b62020005604051602052600052604060002080546060526001810154608052600281015460a0525060605161478557601460c0527f44464d3a4320496e76616c6964206d61726b657400000000000000000000000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b6060518152608051602082015260a051604082015250565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605113156147ef576040516060516000811261511757808201828110615117579050905081525061483956614839565b6040516060517f8000000000000000000000000000000000000000000000000000000000000000811461511757600003600081126151175780820382811161511757905090508152505b565b6202011060805160205260005260406000208060a051602052600052604060002090505460e0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60c0511361492c5760c0517f8000000000000000000000000000000000000000000000000000000000000000811461511757600003600081126151175760e051101561492c576019610100527f44464d3a4320486f6f6b206465627420756e646572666c6f77000000000000006101205261010050610100518061012001601f826000031636823750506308c379a060c052602060e052601f19601f61010051011660440160dcfd5b60e05160405260c05160605261494361010061479d565b6101005160e052620201115460405260c05160605261496361012061479d565b610120516101005260e0516202011060805160205260005260406000208060a051602052600052604060002090505561010051620201115560a0516080517fce64682be365129d68e82326ad253f548f1f36f36772ea07298122b16c4fbdb260c0516101205260e0516101405261010051610160526060610120a3565b600061032052610180516103605260006103805260006002905b8060051b6103600151610340526202010f610340516020526000526040600020805460208160051b01600081601f0160051c60058111615117578015614a5457905b808501548160051b6103a00152600101818118614a3c575b50505050506103a051614a6657614c50565b60006103a05160048111615117578015614c4d57905b8060051b6103c0015161044052610440516040526101a051606052614aa2610460613fb6565b61046051614aaf57614c42565b61044051604052614ac1610480613fa3565b6104805161046052610460515a6101c05060206104c06101c0516101e060008686f190509050614af6573d600060003e3d6000fd5b3d602081183d60201002186104a0526104a06020810151815160200360031b1d90506104805261048051614b2957614c42565b61044051604052614b3b6104c0613fc7565b6104c0516104a05260016104a05118614bb457601d6104c0527f44464d3a4320486f6f6b2063616e6e6f742061646a75737420646562740000006104e0526104c0506104c051806104e001601f826000031636823750506308c379a06104805260206104a052601f19601f6104c051011660440161049cfd5b60026104a05118614be35761048051604052600060605261030051608052600060a052614c22613fda56614c22565b610480516040526102e05160605261030051608052600060a052614c05613fda565b610340516080526104605160a0526104805160c052614c2261483b565b610320516104805180820182811260008312186151175790509050610320525b600101818118614a7c575b50505b6001018181186149fa5750506103205115614c8757610320516040526102e05160605261030051608052600160a052614c87613fda565b61032051815250565b6060516323b872dd60c05260405160e0526080516101005260a05161012052602060c0606460dc6000855af1614ccb573d600060003e3d6000fd5b3d614ce257803b1561511757600161014052614cfa565b60203d106151175760c0518060011c61511757610140525b6101409050511561511757565b62020107546040511115614d725760196060527f44464d3a4320676c6f62616c2064656274206365696c696e670000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b565b60805160ff81116151175762020006015463bdb09f2e60c05260405160e052602060c0602460dc6000855af1614daf573d600060003e3d6000fd5b60203d106151175760c0905051640a3c2abcef818118640a3c2abcef83100218905060a05260605163d4387a9960c05260a05160e052602060c0602460dc6000855af1614e01573d600060003e3d6000fd5b60203d106151175760c05050565b6060516323b872dd60c05260805160e0526040516101005260a05161012052602060c0606460dc6000855af1614e4a573d600060003e3d6000fd5b3d614e6157803b1561511757600161014052614e79565b60203d106151175760c0518060011c61511757610140525b6101409050511561511757565b62020005604051602052600052604060002054614efa5760146060527f44464d3a4320496e76616c6964206d61726b657400000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b565b60206151a4600039600051638da5cb5b604052602060406004605c845afa614f29573d600060003e3d6000fd5b60203d10615117576040518060a01c615117576080526080905051331815614fa857601060a0527f44464d3a43204f6e6c79206f776e65720000000000000000000000000000000060c05260a05060a0518060c001601f826000031636823750506308c379a06060526020608052601f19601f60a0510116604401607cfd5b565b60206151a4600039600051638da5cb5b606052602060606004607c845afa614fd7573d600060003e3d6000fd5b60203d10615117576060518060a01c6151175760a05260a090505133146151155760206151a460003960005163452a932060c052602060c0600460dc845afa615025573d600060003e3d6000fd5b60203d106151175760c0518060a01c615117576101005261010090505133186150b8576040511561511557601f610120527f44464d3a4320477561726469616e2063616e206f6e6c792064697361626c65006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd615115565b601b60c0527f44464d3a43204e6f74206f776e6572206f7220677561726469616e000000000060e05260c05060c0518060e001601f826000031636823750506308c379a0608052602060a052601f19601f60c0510116604401609cfd5b565b600080fd031d18b70d6c15c436d119f63dae3e453f9d3f9d02682ba702dd3f9d01b91b3611ef3f9d12170d8e003c3f9d3f2b00ee25bd336e2755268a25583f9d194b2eed3f9d1af73f9d3f9d3f9d3f9d11cf3f9d28203f9d3b353f9d07ef0d0a001a2a5a007d016424d900bb0000000000000000000000008f25db5ff53b9bb16669b8e59b2f784e9eaac43e000000000000000000000000052fa9d3f0e2e009f038191fb91defeace8fd850

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000052fa9d3f0e2e009f038191fb91defeace8fd8500000000000000000000000008f25db5ff53b9bb16669b8e59b2f784e9eaac43e000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000052b7d2dcc80cd2e4000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000094c317b4c07daeaf2eed8f587bbd8e1bf180dd4d

-----Decoded View---------------
Arg [0] : core (address): 0x052Fa9D3F0e2E009f038191Fb91DEfeAcE8Fd850
Arg [1] : stable (address): 0x8F25db5Ff53B9bB16669b8E59b2f784e9eAaC43E
Arg [2] : monetary_policies (address[]): 0x94C317b4c07DAeAf2eed8f587BBd8e1bf180Dd4d
Arg [3] : debt_ceiling (uint256): 100000000000000000000000000

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000052fa9d3f0e2e009f038191fb91defeace8fd850
Arg [1] : 0000000000000000000000008f25db5ff53b9bb16669b8e59b2f784e9eaac43e
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000052b7d2dcc80cd2e4000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 00000000000000000000000094c317b4c07daeaf2eed8f587bbd8e1bf180dd4d


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.